我有表a,b,c和d,其中:
There are 0 or more b rows for each a row
There are 0 or more c rows for each a row
There are 0 or more d rows for each a row
如果我尝试以下查询:
SELECT a.id, SUM(b.debit), SUM(c.credit), SUM(d.other)
FROM a
LEFT JOIN b on a.id = b.a_id
LEFT JOIN c on a.id = c.a_id
LEFT JOIN d on a.id = d.a_id
GROUP BY a.id
我注意到我创建了一个笛卡尔积,因此我的总和不正确(太大了)。
我看到还有其他SO问题和答案,但是我仍然没有理解如何在单个查询中完成我想要做的事情。在SQL中是否可以编写聚合以下所有数据的查询:
SELECT a.id, SUM(b.debit)
FROM a
LEFT JOIN b on a.id = b.a_id
GROUP BY a.id
SELECT a.id, SUM(c.credit)
FROM a
LEFT JOIN c on a.id = c.a_id
GROUP BY a.id
SELECT a.id, SUM(d.other)
FROM a
LEFT JOIN d on a.id = d.a_id
GROUP BY a.id
在一个查询中?
答案 0 :(得分:2)
您的分析是正确的。不相关JOIN
创建笛卡尔积。
您必须单独进行总和,然后再进行最后添加。这在一个查询中是可行的,您有几个选项:
SELECT a.id, (SELECT SUM(b.debit) FROM b WHERE b.a_id = a.id) + ...
CROSS APPLY
的查询类似于第一个项目符号SELECT a.id, b_sum + c_sum + d_sum
UNION ALL
正如你所建议的那样,在SUM
和GROUP BY
之上。LEFT JOIN
与上述类似的子查询。可能更多......各种解决方案的性能可能略有不同,具体取决于您要选择A
中的行数。
答案 1 :(得分:1)
SELECT a.ID, debit, credit, other
FROM a
LEFT JOIN (SELECT a_id, SUM(b.debit) as debit
FROM b
GROUP BY a_id) b ON a.ID = b.a_id
LEFT JOIN (SELECT a_id, SUM(b.credit) as credit
FROM c
GROUP BY a_id) c ON a.ID = c.a_id
LEFT JOIN (SELECT a_id, SUM(b.other) as other
FROM d
GROUP BY a_id) d ON a.ID = d.a_id
答案 2 :(得分:1)
也可以使用相关子查询来完成:
SELECT a.id
, (SELECT SUM(debit) FROM b WHERE a.id = b.a_id)
, (SELECT SUM(credit) FROM c WHERE a.id = c.a_id)
, (SELECT SUM(other) FROM d WHERE a.id = d.a_id)
FROM a