Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 同一表上的多个左联接_Mysql_Sql_Left Join - Fatal编程技术网

Mysql 同一表上的多个左联接

Mysql 同一表上的多个左联接,mysql,sql,left-join,Mysql,Sql,Left Join,我有两张桌子。 第一个表=>成员{member_id,name,active} 第二个表=>储蓄{储蓄id,会员id,月,年,金额,类型,支付} 成员表 +-----------+--------+--------+ | member_id | name | active | +-----------+--------+--------+ | 105 | Andri | 1 | | 106 | Steve | 1 | | 110 |

我有两张桌子。 第一个表=>成员{member_id,name,active} 第二个表=>储蓄{储蓄id,会员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 |
+-----------+--------+----------+----------+----------+----------+----------+
如您所见,计算不正确,例如,对于成员105,savings2应该是160K。任何关于本案例的疑问的建议


您可能不需要多个左联接,可以按如下方式完成

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
这应该行得通

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

问题是在求和之前要形成完全联接乘积。因此,如果在多个
savings
表中有多个行,则最终会出现重复。如果你愿意,你可以清楚地看到发生了什么。有两种方法可以解决这个问题

  • 在派生表中进行所有求和:

    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
    
  • 连接一次并使用条件和:

    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
    

  • join似乎有问题。。以上答案都是不错的选择

    你也可以使用透视查询

    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
    
    //在这里旋转


    然后试着做一个旋转的家伙。。这也太好了……

    按m.member\u id进行分组不是更简单吗,s.type“然后围绕成员id旋转?我认为成员id=106用于储蓄2有一些错误,实际上它变成了
    80000
    ,您的查询将返回
    160000
    ,您必须在
    s.paid=1
    这样的条件下再添加一个,以获得正确的结果。@Sadikhasan,是的,添加条件将只有
    80000
    ,但看起来OP正在为成员105寻找
    savings2。当您添加条件
    s.paid=1
    时,它应该是160K
    ,然后还可以满足用户需求,并在
    CASE
    函数中校正
    和的输出功率sql。@Charlesliam是的,我应该提到它只起作用,因为它将连接减少到单个表。如果必须对多个表中的记录求和,则不能这样做,因为仍然会得到行的笛卡尔积。