Sql 在同一行中的两个数组_agg列上相交

Sql 在同一行中的两个数组_agg列上相交,sql,postgresql,postgresql-9.5,Sql,Postgresql,Postgresql 9.5,我有一个简单的Postgres数据集,如下所示: INSERT INTO mytable (day, person) values ('Monday', 'A'), ('Monday', 'B'), ('Tuesday', 'A'), ('Thursday', 'B'); 然后,我运行一个查询,生成两个数组_agg,如下所示: SELECT * FROM (select day as d1, array_agg(distinct person) as agg1

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

INSERT INTO mytable (day, person)
values
('Monday', 'A'),
('Monday', 'B'),
('Tuesday', 'A'),
('Thursday', 'B');
然后,我运行一个查询,生成两个数组_agg,如下所示:

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
使用中的函数,您可以编写:

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

Postgresql有侧翼

它可以用来处理记录级字段的内容

d1 | agg1 | d2 | agg2 |配对人 :------- | :---- | :------- | :---- | --------------: 星期一{A,B}星期一{A,B}2 星期四{B}星期一{A,B}1 星期二{A}星期一{A,B}1 星期一{A,B}星期四{B}1 星期四{B}星期四{B}1 星期二{A}星期四{B}0 星期一{A,B}星期二{A}1 星期四{B}星期二{A}0 星期二{A}星期二{A}1
dbfiddle

@user2242044 Thx。顺便说一句,如果将该查询与计数一起用作相关子查询,则可以得到相同的结果<代码>选择*,(选择计数(*)作为匹配项从…。但是相关子查询只能返回1列。而使用SQL则更具可读性,并且可以包含更多的计算列。
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