2011-11-03 97 views
2

我有这两个表
结合MySQL查询SUM()结果使用内部联接

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

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

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,从而倍增的数字组合。你必须首先汇总,然后你加入一个总和一个 out-sum,一切都是groovy。或者是?

如果对于给定的(date, uid)没有value_invalue_out会发生什么情况?或者只有value_in或者只是value_out?您的查询将失败。

我通过使用LEFT JOIN而不是[INNER] JOIN来改进,但您真正需要的是FULL OUTER JOIN-- MySQL中缺少的功能之一。

您可以提供天的列表中一个单独的表和LEFT JOIN两个表到它,或者你可以解决缺少的功能,以两次LEFT JOINUNIONSee here for an example

或者,你可以乘你value_out通过-1 UNION两个表一起,建立一个总和。

但你仍然不会得到一天的行没有任何value_invalue_out,这侵犯了您的描述。

所以,只有干净的解决方案是有一个表中的一个子选择在结果希望所有(date, uid)LEFT JOINtable1的款项和table2它,或UNION ALL三(负table2)和然后总结。

+0

哇,它的工作是什么将导致。比INNER JOIN更好,更快,我需要学习这种查询。谢谢 – skeith

+0

@skeith:我添加了一些改进和修复。你可能想看看。 –

+0

是的,再次感谢您提供的改进和修复,它超出我的预期,将从中学习(我发现它对我来说太高级了) – skeith

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

+0

我在发布我的问题之前也试过这个查询,但仍然产生类似的结果无效的结果 – skeith

+0

比你可能在第二个表中有负值 –

+0

不,没有负值 – skeith

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`