gpt4 book ai didi

sql - 从多个表中获取外键的计数

转载 作者:行者123 更新时间:2023-11-29 11:27:04 24 4
gpt4 key购买 nike

我有 3 个表,表 B 和 C 通过外键引用表 A。我想在 PostgreSQL 中编写一个查询,以获取 A 的所有 ID 以及它们在 B 和 C 中的总出现次数。

   a      |     b      |     c
-----------------------------------
id | txt | id | a_id | id | a_id
---+---- | ---+----- | ---+------
1 | a | 1 | 1 | 1 | 3
2 | b | 2 | 1 | 2 | 4
3 | c | 3 | 3 | 3 | 4
4 | d | 4 | 4 | 4 | 4

所需的输出(只是 A 中的 ID 和 B 和 C 中的总计数):

id | Count
---+-------
1 | 2 -- twice in B
2 | 0 -- occurs nowhere
3 | 2 -- once in B & once in C
4 | 4 -- once in B & thrice in C

到目前为止的 SQL SQL Fiddle :

SELECT a_id, COUNT(a_id)
FROM
( SELECT a_id FROM b
UNION ALL
SELECT a_id FROM c
) AS union_table
GROUP BY a_id

我编写的查询从 B 和 C 获取并计算出现次数。但是如果 key 没有出现在 B 或 C 中,它就不会出现在输出中(例如输出中的 id=2)。我如何从表 A 开始我的选择并加入/联合 B 和 C 以获得所需的输出

最佳答案

如果查询涉及到 b 和/或 c 的大部分,那么先聚合再加入会更高效。
我希望这两个变体要快得多:

SELECT a.id,
, COALESCE(b.ct, 0) + COALESCE(c.ct, 0) AS bc_ct
FROM a
LEFT JOIN (SELECT a_id, count(*) AS ct FROM b GROUP BY 1) b USING (a_id)
LEFT JOIN (SELECT a_id, count(*) AS ct FROM c GROUP BY 1) c USING (a_id);

您需要考虑某些 a_id 根本不存在于 a 和/或 b 中的可能性。 count() 永远不会返回 NULL,但面对 LEFT JOIN 时,这是一种冰冷的安慰,它让您得到 NULL 尽管如此,缺失行的值。您必须准备NULL。使用 COALESCE() .

或者 UNION ALL a_id 来自两个表,聚合,然后 JOIN:

SELECT a.id
, COALESCE(ct.bc_ct, 0) AS bc_ct
FROM a
LEFT JOIN (
SELECT a_id, count(*) AS bc_ct
FROM (
SELECT a_id FROM b
UNION ALL
SELECT a_id FROM c
) bc
GROUP BY 1
) ct USING (a_id);

可能比较慢。但仍然比目前提出的解决方案更快。您可以不用 COALESCE() 并且仍然不会丢失任何行。在这种情况下,您可能偶尔会得到 bc_ctNULL 值。

关于sql - 从多个表中获取外键的计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24745091/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com