在同一行的两个array_agg列上相交

时间:2019-03-20 04:44:21

标签: sql postgresql postgresql-9.5

我有一个简单的Postgres数据集,如下所示:

INSERT INTO mytable (day, person)
values
('Monday', 'A'),
('Monday', 'B'),
('Tuesday', 'A'),
('Thursday', 'B');

然后我运行一个查询,产生两个如下的array_aggs:

SELECT *
FROM (select day as d1,
             array_agg(distinct person) as agg1
      from mytable
      group by day) AS AA
   cross join
     (select day as d2,
             array_agg(distinct person) as agg2
      from mytable
      group by day) AS BB

产生此数据集:

Monday, {A,B}, Monday, {A,B}
Monday, {A,B}, Thursday, {B}
Monday, {A,B}, Tuesday, {A}
Thursday, {B}, Monday, {A,B}
Thursday, {B}, Thursday, {B}
Thursday, {B}, Tuesday, {A}
Tuesday, {A}, Monday, {A,B}
Tuesday, {A}, Thursday, {B}
Tuesday, {A}, Tuesday, {A}

我想在此查询中添加第五列,以标识每一行中agg1和agg2中重复条目的数量。

因此,例如,第一行将为2,第二行将为1。我希望这样做,但这给了我一个模棱两可的语法错误:

SELECT *, count(select unnest(agg1) intersect select unnest(agg2))
FROM (select day as d1,
             array_agg(distinct person) as agg1
      from mytable
      group by day) AS AA
   cross join
     (select day as d2,
             array_agg(distinct person) as agg2
      from mytable
      group by day) AS BB

2 个答案:

答案 0 :(得分:1)

Postgresql具有LATERAL。

可用于对记录级别的字段内容进行某些操作。

create table mytable (day varchar(30), person varchar(1));
INSERT INTO mytable (day, person)
values
('Monday', 'A'),
('Monday', 'B'),
('Tuesday', 'A'),
('Thursday', 'B');
SELECT *
FROM (
  select day as d1,
             array_agg(distinct person) as agg1
      from mytable
      group by day) AS AA
   cross join
     (select day as d2,
             array_agg(distinct person) as agg2
      from mytable
      group by day
) AS BB
CROSS JOIN LATERAL 
(
   SELECT COUNT(*) AS MatchingPersons
   FROM
   (
     SELECT unnest(agg1) person
     INTERSECT
     SELECT unnest(agg2)
   ) q
) lat 
d1       | agg1  | d2       | agg2  | matchingpersons
:------- | :---- | :------- | :---- | --------------:
Monday   | {A,B} | Monday   | {A,B} |               2
Thursday | {B}   | Monday   | {A,B} |               1
Tuesday  | {A}   | Monday   | {A,B} |               1
Monday   | {A,B} | Thursday | {B}   |               1
Thursday | {B}   | Thursday | {B}   |               1
Tuesday  | {A}   | Thursday | {B}   |               0
Monday   | {A,B} | Tuesday  | {A}   |               1
Thursday | {B}   | Tuesday  | {A}   |               0
Tuesday  | {A}   | Tuesday  | {A}   |               1

db <>提琴here

答案 1 :(得分:0)

使用this answer中的函数,您可以编写:

SELECT *, array_length(array_intersect(arr1, arr2), 1) AS repeat_count
FROM /* your query */
相关问题