2014-07-04 60 views
4

我有兩張桌子。 第一表=>構件{member_id,名稱,活性} 第二表=>積蓄{savings_id,member_id,月,年,數量,種類,支付}同一張桌子上的多個左連接

成員表

+-----------+--------+--------+ 
| member_id | name | active | 
+-----------+--------+--------+ 
|  105 | Andri | 1  | 
|  106 | Steve | 1  | 
|  110 | Soraya | 1  | 
|  111 | Eva | 1  | 
|  112 | Sonia | 1  | 
+-----------+--------+--------+ 

儲蓄表

+------------+-----------+-------+------+--------+------+------+ 
| savings_id | member_id | month | year | amount | type | paid | 
+------------+-----------+-------+------+--------+------+------+ 
|   1 |  120 | NULL | NULL | 150000 | 1 | 1 | 
|   14 |  105 |  7 | 2014 | 80000 | 2 | 1 | 
|   15 |  105 |  7 | 2014 | 25000 | 3 | 1 | 
|   16 |  105 |  7 | 2014 | 60000 | 4 | 1 | 
|   17 |  105 |  7 | 2014 | 100000 | 5 | 1 | 
|   18 |  106 |  7 | 2014 | 80000 | 2 | 1 | 
|   19 |  106 |  7 | 2014 | 25000 | 3 | 1 | 
|   20 |  106 |  7 | 2014 | 60000 | 4 | 1 | 
|   21 |  106 |  7 | 2014 | 100000 | 5 | 1 | 
|   31 |  110 |  7 | 2014 | 25000 | 3 | 1 | 
|   32 |  110 |  7 | 2014 | 60000 | 4 | 1 | 
|   33 |  110 |  7 | 2014 | 100000 | 5 | 1 | 
|   34 |  111 |  7 | 2014 | 80000 | 2 | 1 | 
|   35 |  111 |  7 | 2014 | 25000 | 3 | 1 | 
|   36 |  111 |  7 | 2014 | 60000 | 4 | 1 | 
|   37 |  111 |  7 | 2014 | 100000 | 5 | 1 | 
|   38 |  112 |  7 | 2014 | 80000 | 2 | 1 | 
|   39 |  112 |  7 | 2014 | 25000 | 3 | 1 | 
|   40 |  112 |  7 | 2014 | 60000 | 4 | 1 | 
|   41 |  112 |  7 | 2014 | 100000 | 5 | 1 | 
|   85 |  105 |  7 | 2015 | 80000 | 2 | 1 | 
|   86 |  105 |  7 | 2015 | 25000 | 3 | 1 | 
|   87 |  105 |  7 | 2015 | 60000 | 4 | 1 | 
|   88 |  105 |  7 | 2015 | 100000 | 5 | 1 | 
|   89 |  106 |  7 | 2015 | 80000 | 2 |  | 
|   90 |  106 |  7 | 2015 | 25000 | 3 |  | 
|   91 |  106 |  7 | 2015 | 60000 | 4 |  | 
|   92 |  106 |  7 | 2015 | 100000 | 5 |  | 
|  101 |  110 |  7 | 2015 | 80000 | 2 |  | 
|  102 |  110 |  7 | 2015 | 25000 | 3 |  | 
|  103 |  110 |  7 | 2015 | 60000 | 4 |  | 
|  104 |  110 |  7 | 2015 | 100000 | 5 |  | 
|  105 |  111 |  7 | 2015 | 80000 | 2 | 1 | 
|  106 |  111 |  7 | 2015 | 25000 | 3 | 1 | 
|  107 |  111 |  7 | 2015 | 60000 | 4 | 1 | 
|  108 |  111 |  7 | 2015 | 100000 | 5 | 1 | 
|  109 |  112 |  7 | 2015 | 80000 | 2 |  | 
|  110 |  112 |  7 | 2015 | 25000 | 3 |  | 
|  111 |  112 |  7 | 2015 | 60000 | 4 |  | 
|  144 |  110 |  7 | 2014 | 50000 | 1 | 1 | 
+------------+-----------+-------+------+--------+------+------+ 

當會員儲蓄時,他們可以選擇5種儲蓄類型,我想要做的是將會員名單和他們所有的儲蓄。

這是MySQL查詢

SELECT m.member_id, name, 
SUM(s1.amount) as savings1, 
SUM(s2.amount) as savings2, 
SUM(s3.amount) as savings3, 
SUM(s4.amount) as savings4, 
SUM(s5.amount) as savings5 
FROM members m 
LEFT JOIN savings s1 ON s1.member_id = m.member_id AND s1.type = 1 AND s1.paid = 1 
LEFT JOIN savings s2 ON s2.member_id = m.member_id AND s2.type = 2 AND s2.paid = 1 
LEFT JOIN savings s3 ON s3.member_id = m.member_id AND s3.type = 3 AND s3.paid = 1 
LEFT JOIN savings s4 ON s4.member_id = m.member_id AND s4.type = 4 AND s4.paid = 1 
LEFT JOIN savings s5 ON s5.member_id = m.member_id AND s5.type = 5 AND s5.paid = 1 
WHERE 
active = 1 
GROUP BY m.member_id 

這是輸出

+-----------+--------+----------+----------+----------+----------+----------+ 
| member_id | name | savings1 | savings2 | savings3 | savings4 | savings5 | 
+-----------+--------+----------+----------+----------+----------+----------+ 
|  105 | Andri |  NULL | 1280000 | 400000 | 960000 | 1600000 | 
|  106 | Steve |  NULL | 80000 | 25000 | 60000 | 100000 | 
|  110 | Soraya | 50000 |  NULL | 25000 | 60000 | 100000 | 
|  111 | Eva |  NULL | 1280000 | 400000 | 960000 | 1600000 | 
|  112 | Sonia |  NULL | 80000 | 25000 | 60000 | 100000 | 
+-----------+--------+----------+----------+----------+----------+----------+ 

正如你可以看到的計算是不正確的,例如用於savings2部件105應該是160K。任何建議什麼應該是這個案件的查詢。

http://sqlfiddle.com/#!2/9eca9/1

+0

豈不是更簡單做一個'GROUP BY m.member_id,s.type'然後圍繞成員id旋轉? – JRLambert

回答

6

問題是你正在形成完整的產品加盟在總結之前。因此,如果您的多個表中有多於一行,則最終會出現重複。如果你perform the join without summation,你可以清楚地看到發生了什麼。有兩種方法可以解決這個問題。

  1. 是否所有的總和在派生表:

    SELECT m.member_id, name, 
    s1.amount as savings1, 
    s2.amount as savings2, 
    ... 
    FROM members m 
    LEFT JOIN (
        select SUM(amount) as amount, member_id 
        from savings 
        where type = 1 and paid = 1 
        group by member_id 
    ) s1 ON s1.member_id = m.member_id 
    LEFT JOIN (
        select SUM(amount) as amount, member_id 
        from savings 
        where type = 2 and paid = 1 
        group by member_id 
    ) s2 ON s2.member_id = m.member_id 
    ... 
    WHERE active = 1 
    GROUP BY m.member_id 
    
  2. 加入一次,使用條件的總和:

    SELECT m.member_id, name, 
        SUM(CASE WHEN s.type = 1 then s.amount ELSE NULL END) as savings1, 
        SUM(CASE WHEN s.type = 2 then s.amount ELSE NULL END) as savings2, 
        ... 
    LEFT JOIN savings s s2 ON s.member_id = m.member_id AND s.paid = 1 
    WHERE active = 1 
    GROUP BY m.member_id 
    
+0

感謝您的解釋 – l1th1um

+0

'SUM'帶'CASE'功能的力量真正縮短了sql。 – Charlesliam

+0

@Charlesliam是的,我應該提到它只能工作,因爲它減少了連接到一個表。如果您必須將記錄彙總到多個表*中,則無法執行此操作,因爲您仍然可以獲得行的笛卡爾積。 –

5

你也許並不需要多個左連接和可以做的

SELECT 
m.member_id, 
m.name, 
SUM(case when s.type= 1 then s.amount end) as savings1, 
SUM(case when s.type= 2 then s.amount end) as savings2, 
SUM(case when s.type= 3 then s.amount end) as savings3, 
SUM(case when s.type= 4 then s.amount end) as savings4, 
SUM(case when s.type= 5 then s.amount end) as savings5 
FROM savings s 
join members m on m.member_id = s.member_id 
WHERE 
m.active = 1 
GROUP BY m.member_id 
+0

謝謝...我認爲我做得太複雜了:D – l1th1um

+0

我認爲member_id = 106對於saving2有一些錯誤,實際上它變成了'80000',而你的查詢將返回'160000' – Sadikhasan

+0

你必須再添加一個條件's.paid = 1',所以得到正確的結果。 – Sadikhasan

2

這應該工作

SELECT m.member_id, name, 

sum((case when s1.type=1 then s1.amount end)) as savings1, 

sum((case when s1.type=2 then s1.amount end)) as savings2, 

sum((case when s1.type=3 then s1.amount end)) as savings3, 

sum((case when s1.type=4 then s1.amount end)) as savings4, 

sum((case when s1.type=5 then s1.amount end)) as savings5 

FROM members m 

LEFT JOIN savings s1 ON s1.member_id = m.member_id 

WHERE active = 1 and s1.paid=1 

GROUP BY m.member_id 
0

似乎加入有問題.. u能去上面的答案都是不錯的選擇..

U可以使用透視查詢

SELECT m.member_id,s1.type, 
SUM(s1.amount) as savings 
FROM members m 
LEFT JOIN savings s1 ON s1.member_id = m.member_id AND s1.paid = 1 
WHERE active = 1 
GROUP BY m.member_id ,s1.type 

//樞軸這裏

,然後嘗試用於旋轉傢伙..這也將是不錯...