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

时间:2018-12-30 17:32:33

标签: sql postgresql postgresql-9.5

我有一个看起来像这样的表:

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

此处id唯一列,而num文本数组,其中可以包含重复的元素。我想做两个连续行之间的交集之类的事情,以便获得两行num之间的公共元素计数。考虑类似集合的情况,其中重复项仅被考虑一次。例如,对于上表,我期望如下所示:

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

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

2 个答案:

答案 0 :(得分:0)

对于示例数据,此方法有效:

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%是否是您想要的。

答案 1 :(得分:0)

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

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;