postgresql查询视图:为每个作者列出其合著者总数

时间:2018-10-07 00:01:31

标签: sql postgresql

sample data and expected result 尝试创建查询以计算每个作者的合著者总数。

我现有的数据库表将具有 2列bookid及其各自的作者 每个Bookid可能有不止一位作者 而且每位作者可以写多本书。

我想创建一个视图 2列作者姓名和合著者总数

例如,如果book1具有author1,author2,author3,而book2具有author1,author2,author4,则作者1的合著者总数为3

请注意不要重复计算同一位作者。

对此仍然很新,试图将其写为表,但很混乱。 谢谢!

样本数据:

db<>fiddle

person_id   person_name   book_id
2           B             1
3           C             2
4           D             2
5           E             2
3           C             3
4           D             3
6           F             3
4           D             4
8           H             4
9           I             4
10          J             4

预期结果:

person_name   coauthors
B             0
C             3
D             6
E             2
F             2
H             3
I             3
J             3

ps:我大约有2000多行作者和bookid

2 个答案:

答案 0 :(得分:0)

假设表Books(author1, ... author4, bookid, ...)的某些author*值可能为空。另外,辅助BookAuthors(bookid, author)表允许任意数量的作者以及更简单的查询

这看起来很混乱,但是利用了UNION(而不是UNION ALL)来进行隐式DISTINCT

select first, count(distinct second)
from (select author1 first, author2 second from Books union
      select author1, author3 from Books union
      select author1, author4 from Books union
      select author2, author1 from Books union
      select author2, author3 from Books union
      select author2, author4 from Books union
      select author3, author1 from Books union
      select author3, author2 from Books union
      select author3, author4 from Books union
      select author4, author1 from Books union
      select author4, author2 from Books union
      select author4, author3 from Books
) coauthors where first is not null and second is not null

答案 1 :(得分:0)

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创建行,其中某本书的每个作者彼此关联。例如,对于book_id = 2,它将创建对

(C, C),
(C, D),
(C, E),
(D, C),
(D, D),
(D, E),
(E, C),
(E, D),
(E, E)

每隔book_id完成一次。现在我们可以通过作者的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


通知:如果给定的表是您的真实表,我建议对其进行规范化。您应该有两个单独的表格:一个用于作者的详细信息,另一个用于与其书籍的关联。想象一下,您可能想要保留作者的全名(也许在两列中),他们的生日和许多其他数据。对他们写的每一本书重复所有这些数据并不是一个好主意。只需将其ID与书籍ID结合起来即可。