具有多个外连接的SQL求和

时间:2014-04-24 23:02:19

标签: sql

我有表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

在一个查询中?

3 个答案:

答案 0 :(得分:2)

您的分析是正确的。不相关JOIN创建笛卡尔积。

您必须单独进行总和,然后再进行最后添加。这在一个查询中是可行的,您有几个选项:

  • SELECT中的子请求: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正如你所建议的那样,在SUMGROUP 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