使用内连接组合mysql查询SUM()结果

时间:2011-11-03 00:57:04

标签: mysql sql

我有这两张桌子

table1 : date | uid | value_in
table2 : date | uid | value_out 

每天,无论交易/记录的数量如何,每个uid都会收到进出的余额值

我想要做的是将查询结果组合成这样的

date | uid | value_in | value_out | (value_in-value_out) as balance

但是,当我执行此查询时

SELECT 
  a.date,
  a.uid,
  SUM(a.value_in),
  SUM(b.value_out),
  (SUM(a.value_in)-SUM(b.value_out)) AS balance
FROM table1 a
INNER JOIN table2 b ON a.date=b.date AND a.uid=b.uid
GROUP BY a.date, a.uid

它产生无效结果(SUM加倍或三倍) 我应该如何修改我的查询,以便它不会产生加倍的结果?

3 个答案:

答案 0 :(得分:3)

首先构建总和,然后加入。像这样:

SELECT i.uid
      ,i.date
      ,i.v_in
      ,COALESCE(o.v_out, 0) AS v_out
      ,(i.v_in - COALESCE(o.v_out, 0)) AS balance
FROM (
    SELECT date
          ,uid
          ,SUM(value_in) AS v_in
    FROM   table1
    GROUP  BY 1,2
    ) i
LEFT JOIN (
    SELECT date
          ,uid
          ,SUM(value_out) AS v_out
    FROM   table2
    GROUP  BY 1,2
    ) o USING (date, uid)

您拥有它的方式,每个value_in都会与每个匹配的value_out合并,从而将这些数字相乘。您必须首先汇总,然后加入一个一个总和,并且一切都很常规。或者是吗?

如果给定value_in没有value_out(date, uid)会怎样?或者仅value_in或仅value_out?您的查询将失败。

我使用LEFT JOIN代替[INNER] JOIN进行了改进,但您真正想要的是FULL OUTER JOIN - MySQL中缺少的功能之一。

您可以在单独的表格中提供天数列表,也可以在LEFT JOIN两个表格中提供,或者您可以使用LEFT JOINUNION两次解决缺失的功能。 See here for an example

您可以将value_out-1两个表格相乘,并构建一个总和。

仍然不会在没有任何value_invalue_out的情况下获得一行,这违反了您的描述。

因此,唯一干净的解决方案是在结果中包含您想要的所有(date, uid)的表格,LEFT JOINtable1和{{的总和1}},或者table2子选项中的三个(负UNION ALL),然后总结。

答案 1 :(得分:0)

如果您尝试这样做会产生什么结果

SELECT 
  a.date,
  a.uid,
  SUM(a.value_in),
  SUM(b.value_out),
  SUM(a.value_in-b.value_out) AS balance 
FROM table1 a
INNER JOIN table2 b ON a.date=b.date AND a.uid=b.uid
GROUP BY a.date, a.uid

SUM(a.value_in-b.value_out) AS balance在逻辑上应与(SUM(a.value_in)-SUM(b.value_out)) AS balance相同,但可能不与mysql

相同

答案 2 :(得分:0)

SELECT 
  a.date,
  a.uid,
  SUM(a.value_in),
  SUM(b.value_out),
  SUM(a.value_in-b.value_out) AS balance 
FROM table1 a
INNER JOIN table2 b ON a.date=b.date AND a.uid=b.uid
GROUP BY a.date, a.uid`enter code here`