如何实现这个mysql组查询
我有两张桌子A和B。 我的目标是列出A中的每一行,同时附上B中“金额”的总和 像这样:如何实现这个mysql组查询,mysql,group-by,Mysql,Group By,我有两张桌子A和B。 我的目标是列出A中的每一行,同时附上B中“金额”的总和 像这样: SELECT a.name, SUM(b.amount) as amount FROM a LEFT JOIN b ON a.id = b.a_id GROUP BY a.id 在此之前没有问题,但我还需要检查B表的'shop_id'是否与某个值匹配,如果匹配,我希望该行的'amount',而不是所有分组行的总和。我希望这是可以理解的 Table A id name --
SELECT a.name,
SUM(b.amount) as amount
FROM a
LEFT JOIN b ON a.id = b.a_id
GROUP BY a.id
在此之前没有问题,但我还需要检查B表的'shop_id'是否与某个值匹配,如果匹配,我希望该行的'amount',而不是所有分组行的总和。我希望这是可以理解的
Table A
id name
----------------
1 john
2 doe
3 smith
Table B
a_id amount shop
-----------------------
1 4 1
1 3 2
2 2 2
2 7 3
3 3 3
3 1 2
“车间”为1时的预期结果:
name amount shop
---------------------
john 4 1 //no SUM, only the value of amount where shop=1
doe 9 0 //sum(7,2) because shop is not 1
smith 4 0 //sum(3,1)
我想在SUM选择中使用一个if语句,类似于此,但是下面的语句返回的不是所需的groupped行值
SELECT a.name,
( CASE
WHEN b.shop <> 1 THEN Sum(b.amount)
ELSE b.amount
end ) AS amount,
( CASE
WHEN b.shop <> 1 THEN 0
ELSE b.shop
end ) AS shop
FROM a
LEFT JOIN b
ON a.id = b.a_id
GROUP BY a.id
有什么想法吗?有没有一种方法可以把这种情况告诉大家,比如:case shop1 THEN。。。。ELSE GROUP BY a.id???使用所谓的条件聚合是正确的。以下是一个可以工作的版本:
SELECT
a.name,
CASE WHEN MAX(CASE WHEN b.shop = 1 THEN 1 ELSE 0 END) > 0
THEN SUM(CASE WHEN b.shop = 1 THEN b.amount ELSE 0 END)
ELSE SUM(b.amount) END AS amount,
MAX(CASE WHEN b.shop = 1 THEN 1 ELSE 0 END) AS shop
FROM a
LEFT JOIN b
ON a.id = b.a_id
GROUP BY
a.name;
使用所谓的条件聚合是正确的。以下是一个可以工作的版本:
SELECT
a.name,
CASE WHEN MAX(CASE WHEN b.shop = 1 THEN 1 ELSE 0 END) > 0
THEN SUM(CASE WHEN b.shop = 1 THEN b.amount ELSE 0 END)
ELSE SUM(b.amount) END AS amount,
MAX(CASE WHEN b.shop = 1 THEN 1 ELSE 0 END) AS shop
FROM a
LEFT JOIN b
ON a.id = b.a_id
GROUP BY
a.name;
您将需要与表b左联接两次。
第一次联接将允许计算和。
只有当shop=1时,第二个联接才会联接。因此,如果我们由于第二次加入而得到一些非空值,我们会考虑,否则,和
请尝试以下操作:
SELECT
a.id,
a.name,
COALESCE(MAX(b2.amount), SUM(b1.amount)) AS amount,
COALESCE(b2.shop, 0) AS shop
FROM a
LEFT JOIN b AS b1 ON a.id = b1.a_id
LEFT JOIN b AS b2 ON a.id = b2.a_id AND b2.shop = 1
GROUP BY a.id, a.name
结果
您将需要与表b左联接两次。
第一次联接将允许计算和。
只有当shop=1时,第二个联接才会联接。因此,如果我们由于第二次加入而得到一些非空值,我们会考虑,否则,和
请尝试以下操作:
SELECT
a.id,
a.name,
COALESCE(MAX(b2.amount), SUM(b1.amount)) AS amount,
COALESCE(b2.shop, 0) AS shop
FROM a
LEFT JOIN b AS b1 ON a.id = b1.a_id
LEFT JOIN b AS b2 ON a.id = b2.a_id AND b2.shop = 1
GROUP BY a.id, a.name
结果
我正在测试,到目前为止看起来不错。谢谢你的快速回复。您认为Madhur的解决方案会运行得更慢吗?好问题,您可以测试这两个查询。他的答案看起来比我的更干净、更复杂。当shop=1时,你可以用Max代替SUM;否则,如果OP的车间数据重复=1;然后它将计算总和,而不仅仅是其中一个值+1我正在测试,到目前为止看起来不错。谢谢你的快速回复。您认为Madhur的解决方案会运行得更慢吗?好问题,您可以测试这两个查询。他的答案看起来比我的更干净、更复杂。当shop=1时,你可以用Max代替SUM;否则,如果OP的车间数据重复=1;然后它将计算总和,而不仅仅是其中一个值+1这会得到一个更高的投票权,因为它太复杂了,实际上看着它很痛苦。@TimBiegeleisen谢谢;但我怀疑它的效率,因为是双连接。@Ninet9您对这两个查询进行了基准测试吗?结果如何?不,我还没有把数据库填满。但是效率是非常重要的,表A大约有10000行,B大约有50000行,两者都有更多的字段。首先,Tim的解决方案似乎更快,但我将测试这两种方法。@Ninet9请参见:。谢谢:这是一个很好的选择,因为它太复杂了,看着它真的很痛苦。@TimBiegeleisen谢谢;但我怀疑它的效率,因为是双连接。@Ninet9您对这两个查询进行了基准测试吗?结果如何?不,我还没有把数据库填满。但是效率是非常重要的,表A大约有10000行,B大约有50000行,两者都有更多的字段。首先,Tim的解决方案似乎更快,但我将测试这两种方法。@Ninet9请参见:。谢谢: