【问题标题】:PostgreSQL Select distinct values of comma separated values column excluding subsetsPostgreSQL选择逗号分隔值列的不同值,不包括子集
【发布时间】:2023-03-21 19:55:01
【问题描述】:

假设有一个表 foobar 带有逗号分隔值 ('a,b' , 'a,b,c' , 'A B C D' , 'd,e') 如何选择最大的组合并排除该组合中包含的所有子集(最大的一个):

上面数据集的例子,结果应该是:

('a,b,c,d' , 'd,e' ) 和前两个实体 ('a,b', 'a,b,c') 被排除在外,因为它们是 ('a,b,c,d') 的子集。

考虑到逗号分隔字符串中的所有值都按字母顺序排序

我尝试了以下查询,但结果似乎离我需要的有点远:

select distinct a.bar from foo a   inner join foo b
on a.bar like '%'|| b.bar||'%' 
and a.bar != b.bar

【问题讨论】:

  • ('a,b' , 'a,b,c' , 'a,b,c,d' , 'd,e') 是一行一个列中的单个值吗?

标签: sql postgresql


【解决方案1】:

您可以使用string_to_array() 将字符串拆分为一个数组。使用包含运算符@>,您可以检查一个数组是否包含另一个数组。 (见"9.18. Array Functions and Operators"。)

NOT EXISTS 子句中使用它。 fi.ctid <> fo.ctid 是为了确保被比较的行对的物理地址不相等,因为一行的数组当然会包含与同一行比较的数组。

SELECT fo.bar
       FROM foo fo
       WHERE NOT EXISTS (SELECT *
                                FROM foo fi
                                WHERE fi.ctid <> fo.ctid
                                      AND string_to_array(fi.bar, ',') @> string_to_array(fo.bar, ','));

SQL Fiddle

但我无法抗拒:不要在关系数据库中使用逗号分隔的字符串。你有更好的东西。它被称为“表”。

【讨论】:

    【解决方案2】:

    先将字符串处理成字符集,然后将字符集与自身交叉连接,不包括两边字符集相同的行。

    接下来,在 HAVING 子句中聚合并使用 BOOL_OR 来过滤掉作为任何其他字符集子集的任何字符集

    在 cte 中定义了一个示例表,查询变为:

    WITH foo(bar) AS (SELECT '("a,b" , "a,b,c" , "a,b,c,d" , "d,e")'::TEXT)
    SELECT bar, string_to_array(elems[1], ',') not_subset
    FROM foo
    CROSS JOIN regexp_matches(bar, '[\w|,]+', 'g') elems 
    CROSS JOIN regexp_matches(bar, '[\w|,]+', 'g') elems2
    WHERE elems2[1] != elems[1] 
      -- my regex also matches the ',' between sets which need to be ignored
      -- alternatively, i have to refine the regex
      AND elems2[1] != ','
      AND elems[1] != ','
    GROUP BY 1, 2
    HAVING NOT BOOL_OR(string_to_array(elems[1], ',') <@ string_to_array(elems2[1], ','))
    

    产生输出

    bar                                     not_subset
    '("a,b" , "a,b,c" , "a,b,c,d" , "d,e")' {'d','e'}
    '("a,b" , "a,b,c" , "a,b,c,d" , "d,e")' {'a','b','c','d'}
    

    example in sql fiddle

    【讨论】:

      猜你喜欢
      • 2020-01-15
      • 2021-01-19
      • 2021-02-06
      • 2017-06-22
      • 2020-01-19
      • 2019-08-23
      • 1970-01-01
      • 1970-01-01
      • 2020-04-26
      相关资源
      最近更新 更多