我不知道该怎么说这个,所以请帮我标题。 :)
我有两张桌子。我们称他们为A
和B
。 B
表的a_id
外键指向A.id
。现在我想编写一个SELECT
语句来获取所有A
条记录,另外一列包含结果中每行B
行的A
条记录数集。
我现在正在使用Postgresql 9,但我想这会是一个通用的SQL问题?
编辑:
最后,我选择了触发缓存解决方案,每次A.b_count
更改时,都会通过函数更新B
。
答案 0 :(得分:76)
SELECT A.*, (SELECT COUNT(*) FROM B WHERE B.a_id = A.id) AS TOT FROM A
答案 1 :(得分:26)
我认为@intgr在另一个答案中的评论非常有价值我将此作为替代答案提出,因为此方法允许您有效地过滤计算列。
SELECT
a.*,
COUNT(b.id) AS b_count
FROM a
INNER JOIN b on b.a_id = a.id
WHERE a.id > 50 AND b.ID < 100 -- example of filtering joined tables, optional
GROUP BY a.id
HAVING COUNT(b.id) > 10 -- example of filtering calculated column, optional
ORDER BY a.id
答案 2 :(得分:10)
上面给出的子查询解决方案效率低下。触发器解决方案可能在大多数读取数据库中是最好的,但是对于记录,这里的连接方法将比子查询执行得更好:
SELECT a.id, a.xxx, count(*)
FROM a JOIN b ON (b.a_id = a.id)
GROUP BY a.id, a.xxx
如果你正在使用Django ORM,你可以简单地写一下:
res = A.objects.annotate(Count('b'))
print res[0].b__count # holds the result count
答案 3 :(得分:5)
根据我的测试,接受的答案效率低(慢)。表B的子查询针对表A的每一行执行。我使用基于分组和连接的以下方法。它工作得更快:
SELECT A.id, QTY.quantity FROM A
LEFT JOIN
(SELECT COUNT(B.a_id) AS quantity, B.a_id FROM B GROUP BY B.a_id) AS QTY
ON A.id = QTY.a_id
另一种变体:
SELECT A.id, COUNT(B.a_id) AS quantity FROM A
LEFT JOIN B ON B.a_id = A.id
GROUP BY A.id
答案 4 :(得分:0)
回答我自己的问题:
SELECT a.id, a.other_column, ...,
(SELECT COUNT(*) FROM b where b.a_id = a.id) AS b_count
FROM a;
答案 5 :(得分:0)
虽然子查询可能效率较低,但效率低多少取决于用例。另一个需要考虑的是正在使用的过滤器。
我有一个表 A 的“批准者” 我有一个“审批任务”表 B
我想显示所有审批者的列表以及他们拥有的 ACTIVE 审批任务的数量。现在,我对 SQL 的了解有限,但是无论我尝试使用不同类型的连接做什么,我的批准者列表都不完整。为什么?我需要在表 B 上有一个过滤器,以便只返回活动任务。如果审批人只有非活动/已完成任务,则不计入。这应该显示 0,但由于某种原因,它根本不显示该行。
所以,我使用了一个子查询,它完美地工作。