Перекрытие столбца на основе другого столбца - PullRequest
2 голосов
/ 20 марта 2019

У меня есть простая таблица в Postgres, которая содержит дни недели и людей.

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

Я бы хотел найти количество перекрывающихся людей для каждой пары дней. Например, в понедельник есть лица A и B. Во вторник есть только лица B, поэтому строка будет выглядеть следующим образом:

('Monday', 'Tuesday', 1)

Окончательный результат должен выглядеть следующим образом:

('Monday', 'Monday', 2),
('Monday', 'Tuesday', 1),
('Monday', 'Wednesday', 2),
('Monday', 'Thursday', 1),
('Tuesday', 'Tuesday', 1),
('Tuesday', 'Monday', 1),
('Tuesday', 'Wednesday', 1),
('Tuesday', 'Thursday', 0),
('Wednesday', 'Wednesday', 2),
('Wednesday', 'Monday', 2),
('Wednesday', 'Tuesday', 1),
('Wednesday', 'Thursday', 1),
('Thursday', 'Thursday', 1),
('Thursday', 'Monday', 1),
('Thursday', 'Tuesday', 0),
('Thursday', 'Wednesday', 1)

Я играл с перекрестными соединениями и пересечениями, но, кажется, ничто не дает правильного результата.

1 Ответ

3 голосов
/ 20 марта 2019

Используйте самостоятельное соединение:

select t1.day, t2.day, count(distinct t2.person) as num_overlaps
from mytable t1 join
     mytable t2
     on t1.person = t2.person
group by t1.day, t2.day
order by t1.day, t2.day;

EDIT:

Я вижу, вы хотите также включить нулевое перекрытие. Это немного сложнее. Для этого вам нужно сгенерировать все комбинации дней, а затем объединить данные:

select d1.day, d2.day, count(distinct t2.person)
from (select distinct day from mytable) d1 cross join
     (select distinct day from mytable) d2 left join
     mytable t1
     on t1.day = d1.day left join
     mytable t2
     on t2.day = d2.day and t2.person = t1.person
group by d1.day, d2.day
order by d1.day, d2.day;

Здесь - это дБ <> скрипка.

...