2011-11-03 95 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`