demo: db <> fiddle
SELECT
a.person_name,
count(distinct b.person_id) - 1 as coauthors
FROM authors a
INNER JOIN authors b
ON a.book_id = b.book_id
GROUP BY a.person_id, a.person_name
ORDER BY a.person_name
INNER JOIN
для самой таблицы на их book_id
s создает строки, с которыми связан каждый автор определенной книгидруг с другом.Например, для book_id = 2
создаются пары
(C, C),
(C, D),
(C, E),
(D, C),
(D, D),
(D, E),
(E, C),
(E, D),
(E, E)
Это делается для каждого book_id
.Теперь мы можем GROUP
по идентификатору автора (person_id
), который дает, например, для D
: (C, D, E)
(и всех других соавторов из других книг).
Потому что, например, совокупностьдля D
и все его книги выглядят как (C, D, E, C, D, F, D, H, I, J)
, мы должны отфильтровывать каждое удвоенное значение.Это то, что DISTINCT
делает.
Теперь это выглядит как (C, D, E, F, H, I, J)
, что делает счет 7
.Напоследок мы не хотим считать самого автора.Вот почему мы в конце вычитаем 1
.
Примечание : Если данная таблица является вашей реальной таблицей, я бы порекомендовал ее нормализовать.У вас должно быть две отдельные таблицы: одна для сведений об авторе и одна для связи с их книгами.Представьте себе, что вы можете хранить полные имена авторов (возможно, в двух столбцах), их дни рождения и многие другие данные.Не было бы хорошей идеей повторять все эти данные для каждой книги, которую они написали.Просто объедините их идентификаторы с идентификаторами книг.