MySQL中GROUP BY导致统计计数异常问题求助
解决按客户分组统计购买与退货数量的SQL问题
嘿,我来帮你搞定这个统计问题~先理清楚你的需求和现有问题:
你的原始数据表
id client trans_date returned 1 bob 20180301 0 2 frank 20180301 0 3 bob 20180401 1
期望的统计结果
name bought returned bob 1 1 frank 1 0
你的原SQL存在的问题
你写的SQL有几个关键错误导致没有得到正确结果:
- 字段名不匹配:原表字段是
client、trans_date、returned,但你用了soldto、sdate、return(return还是SQL关键字,容易触发语法错误) - 聚合函数使用错误:你用
IF(return=0,count(id),'0')的方式不对,COUNT()会统计分组内的所有行,不会因为IF的条件过滤,所以没法得到正确的分类统计数
正确的SQL写法
这里提供两种可行的写法,核心是用SUM()来累加符合条件的行数:
方法1:使用CASE WHEN(兼容性更好,适用于多数SQL数据库)
SELECT client AS name, SUM(CASE WHEN returned = 0 THEN 1 ELSE 0 END) AS bought, SUM(CASE WHEN returned = 1 THEN 1 ELSE 0 END) AS returned FROM sales WHERE trans_date BETWEEN '20180201' AND '20180501' GROUP BY client;
方法2:使用IF函数(适合MySQL等支持IF的数据库)
SELECT client AS name, SUM(IF(returned = 0, 1, 0)) AS bought, SUM(IF(returned = 1, 1, 0)) AS returned FROM sales WHERE trans_date BETWEEN '20180201' AND '20180501' GROUP BY client;
逻辑解释
SUM(CASE WHEN returned = 0 THEN 1 ELSE 0 END):遍历分组内的每一行,当returned=0(未退货,即有效购买)时记为1,否则记为0,最后累加的结果就是该客户的购买数量- 同理,
SUM(CASE WHEN returned = 1 THEN 1 ELSE 0 END)统计的是退货数量 - 日期条件根据你的需求调整成和原表
trans_date匹配的格式即可
内容的提问来源于stack exchange,提问作者Mike The Elf
相关产品推荐
相关产品推荐

