selectPostgres SELECT语句中另一个表中的行数
我不知道如何说这个,所以请帮助我的标题。 🙂
我有两张桌子。 我们称他们为A
和B
B
表有一个指向A.id
的a_id
外键。 现在我想编写一个SELECT
语句来获取所有的A
logging,并且在结果集中的每一行都有一个包含每行A
行的B
logging数的附加列。
我现在正在使用Postgresql 9,但我想这将是一个通用的SQL问题?
编辑:
最后,我去了触发caching解决scheme,其中A.b_count
通过一个函数每次更改B
更新。
SELECT A.*, (SELECT COUNT(*) FROM B WHERE B.a_id = A.id) AS TOT FROM A
我认为@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 tabled GROUP BY a.id HAVING COUNT(b.id) > 10 -- example of filtering calculated column ORDER BY a.id
上面给出的子查询解决scheme效率低下。 触发器解决scheme在大部分读取的数据库中可能是最好的,但是对于这个logging来说,这是一个比子查询更好的联接方法:
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
基于我的testing,接受的答案是低效的(慢)。 表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
回答我自己的问题:
SELECT a.id, a.other_column, ..., (SELECT COUNT(*) FROM b where b.a_id = a.id) AS b_count FROM a;