在Postgres SELECT语句中选择另一个表中的行数

时间:2010-12-26 23:05:36

标签: sql postgresql

我不知道该怎么说这个,所以请帮我标题。 :)

我有两张桌子。我们称他们为ABB表的a_id外键指向A.id。现在我想编写一个SELECT语句来获取所有A条记录,另外一列包含结果中每行B行的A条记录数集。

我现在正在使用Postgresql 9,但我想这会是一个通用的SQL问题?

编辑:

最后,我选择了触发缓存解决方案,每次A.b_count更改时,都会通过函数更新B

6 个答案:

答案 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,但由于某种原因,它根本不显示该行。

所以,我使用了一个子查询,它完美地工作。