在 Postgres 中获取文本数组列的公共值计数

Getting common value count of text array column in Postgres

我有一个 table 看起来像这样:

id   num
---  ----
1    {'1','2','3','3'}
2    {'2','3'}
3    {'5','6','7'}

这里 id 是一个 unique 列,num 是一个 文本数组 可以包含重复元素.我想做一些类似两个连续行之间的交集的事情,以便我得到两行 num 之间的公共元素数。考虑类似集合的东西,其中重复项只被考虑一次。例如,对于上面的 table,我期望如下所示:

id1   id2  count
---   ---  -----
1      2    2
1      3    0
2      1    2
2      3    0
3      1    0
3      2    0

没有必要像上面那样得到输出。我唯一关心的部分是 count.

我有以下查询,它只给出一个 ID 与另一个 ID 的输出:

select unnest(num) from emp where id=1
intersect
select unnest(num) from emp where id=2

我如何概括它以获得所需的输出?

对于示例数据,这有效:

with t as (
      select v.*
      from (values (1000, array['acct', 'hr']), (1005, array['dev', hr'])) v(empid, depts)
     )
select t1.empid, t2.empid,
       (select count(distinct d1)
        from unnest(t1.depts) d1 join
             unnest(t2.depts) d2
             on d1 = d2
       ) cnt
from t t1 join
     t t2
     on t1.empid < t2.empid;

不过,我不能 100% 确定这是您的意图。

一种直接的方法是将未嵌套数组的交集放在子查询中并获取它们的计数。

SELECT t1.id id1,
       t2.id id2,
       (SELECT count(*)
               FROM (SELECT num1.num
                            FROM unnest(t1.num) num1(num)
                     INTERSECT
                     SELECT num2.num
                            FROM unnest(t2.num) num2(num)) x) count
       FROM emp t1
            INNER JOIN emp t2
                       ON t2.id > t1.id
       ORDER BY t1.id,
                t2.id;

如果你只关心数组是否共享元素而不关心确切的数量,你也可以使用重叠运算符&&

SELECT t1.id id1,
       t2.id id2,
       t1.num && t2.num intersection_not_empty
       FROM emp t1
            INNER JOIN emp t2
                       ON t2.id > t1.id
       ORDER BY t1.id,
                t2.id;