Mysql 同一表上的多个左联接
我有两张桌子。 第一个表=>成员{member_id,name,active} 第二个表=>储蓄{储蓄id,会员id,月,年,金额,类型,支付} 成员表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 |
+-----------+--------+--------+
| 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是的,我应该提到它只起作用,因为它将连接减少到单个表。如果必须对多个表中的记录求和,则不能这样做,因为仍然会得到行的笛卡尔积。