postgresql 如何计算文本字段中的元素

vof42yt1  于 2023-06-29  发布在  PostgreSQL
关注(0)|答案(3)|浏览(160)

在我的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||

suzh9iv8

suzh9iv81#

首先,存储相关id的分隔列表是一个非常糟糕的计划。正如@ErwinBrandstetter所指出的,一个规范化的表单和为每个相关的id创建一个单独的表是一个好得多的方法。但是,由于您只需要相关id的数量:
如果字符串保证以分隔符开始和结束,那么你只需要2个简单的字符串函数:replace()length()。使用replace删除分隔符。然后,结果字符串长度的差异给出了删除的分隔符的数量。由于在字符串的开始和结束处都有一个分隔符,因此删除的分隔符的数量比元素的数量大1。因此,相关的结果数为:(参见demo

select length(total_ids) - length( replace(total_ids,'|', '')) - 1 "total ids"
  from candidates;
lmyy7pcs

lmyy7pcs2#

使用这里的函数String functions和这里的函数Array functions

select array_length(string_to_array(trim('|ABX1-001|ABX1-002|ABX1-004|ABX1-005|', '|'), '|'), 1);

 array_length 
--------------
            4

trim函数删除开头和结尾的|,然后string_to_array在剩余的|上拆分字符串,以生成一维文本数组。然后,array_length函数计算第1个数组维度中的元素数。
候补:

select count(*) from  string_to_table(trim('|ABX1-001|ABX1-002|ABX1-004|ABX1-005|', '|'), '|');

trim做同样的事情,然后string_to table生成一个表,每个元素都在一行中,然后使用count计数。

q5iwbnjs

q5iwbnjs3#

那要看情况

如果我们可以依靠每个键8个字符和每个分隔符1个字符的固定长度,那么整数除法是一种非常简单和快速的方法:

SELECT *, length(total_ids) / 9 AS current_ids_count
FROM   candidates;

Integer division会截断,因此前导和悬挂噪声并不重要,只要它的总数低于9个字符。

如果长度可以变化,但我们可以依赖于分隔符|(并且没有前导或悬挂白色),那么考虑Adrian的解决方案。

通常情况下,最好将这些数据存储为实际数组,或者在normalized form中作为单独的表,与candidates有n:1的关系。

相关问题