在我的PostgreSQL DB中,我有一个表,其中包含一个text类型的字段,其中包含一个字符串,如下所示:
|ABX1-001|ABX1-002|ABX1-004|ABX1-005|
我想计算文本字段current_ids
内的项目。这是表的结构:
CREATE TABLE "public"."candidates" (
"day" timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP,
"study_id" varchar(6) NOT NULL,
"site_id" varchar(32),
"status" varchar(32) NOT NULL,
"total" int4 NOT NULL,
"current" int4 NOT NULL,
"referrer_token" varchar(255) NOT NULL DEFAULT 'NO_REFERRER_TOKEN'::character varying,
"total_ids" text NOT NULL DEFAULT '|'::text,
"current_ids" text NOT NULL DEFAULT '|'::text
);
一些样本数据:
| ABX1|美国-1|不完整|4| 4|无推荐人令牌|ABX1-001 ABX1-002 ABX1-004 ABX1-004||ABX1-001| ABX1-002| ABX1-004| ABX1-004||
| - -----|- -----|- -----|- -----|- -----|- -----|- -----| ------------ |
| ABX1|美国-1|不完整|九个|七个|无推荐人令牌|ABX1-009 ABX1 -010 ABX1-011 ABX1-012 ABX1-013 ABX1-014 ABX1-016 ABX1-018 ABX1-020||ABX1-009| ABX1-010| ABX1-011| ABX1-012| ABX1-013| ABX1-014| ABX1-016| ABX1-018| ABX1-020||
3条答案
按热度按时间suzh9iv81#
首先,存储相关id的分隔列表是一个非常糟糕的计划。正如@ErwinBrandstetter所指出的,一个规范化的表单和为每个相关的id创建一个单独的表是一个好得多的方法。但是,由于您只需要相关id的数量:
如果字符串保证以分隔符开始和结束,那么你只需要2个简单的字符串函数:
replace()
和length()
。使用replace删除分隔符。然后,结果字符串长度的差异给出了删除的分隔符的数量。由于在字符串的开始和结束处都有一个分隔符,因此删除的分隔符的数量比元素的数量大1。因此,相关的结果数为:(参见demo)lmyy7pcs2#
使用这里的函数String functions和这里的函数Array functions:
trim
函数删除开头和结尾的|
,然后string_to_array
在剩余的|
上拆分字符串,以生成一维文本数组。然后,array_length
函数计算第1个数组维度中的元素数。候补:
trim
做同样的事情,然后string_to table
生成一个表,每个元素都在一行中,然后使用count
计数。q5iwbnjs3#
那要看情况
如果我们可以依靠每个键8个字符和每个分隔符1个字符的固定长度,那么整数除法是一种非常简单和快速的方法:
Integer division会截断,因此前导和悬挂噪声并不重要,只要它的总数低于9个字符。
如果长度可以变化,但我们可以依赖于分隔符
|
(并且没有前导或悬挂白色),那么考虑Adrian的解决方案。通常情况下,最好将这些数据存储为实际数组,或者在normalized form中作为单独的表,与
candidates
有n:1的关系。