MySQL按姓名统计成功、失败次数 查询结果不符合预期如何解决
问题背景
存在名为buggy的业务表,包含3个字段:
id:INT类型name:VARCHAR类型,存储人员姓名bug:INT类型,取值仅为0或1,其中0代表操作失败/故障,1代表操作成功;无对应类别的记录时,该类别计数返回0或null均可
需求为按姓名分组,统计每个人员对应的失败总次数、成功总次数。
原有错误查询写法如下:
SELECT name, CASE WHEN bug = 0 THEN COUNT(bug) END AS failure, CASE WHEN bug = 1 THEN COUNT(bug) END AS success FROM buggy GROUP BY name;
该写法执行结果不符合预期,仅能返回单类别的计数,另一列返回null。
错误原因
CASE判断的执行顺序早于聚合函数,分组后MySQL会从分组结果中随机取一条记录的bug值做WHEN条件判断,只有匹配到的分支会执行COUNT(bug)统计全组记录数,未匹配的分支直接返回null,因此无法实现分类计数。
正确写法
需要将条件判断放在聚合函数内部,仅对符合条件的记录做计数,两种常用实现如下:
写法1:MySQL 简写(利用布尔表达式返回值特性)
MySQL中条件判断成立时返回1、不成立返回0,直接用SUM对条件结果求和即可得到对应分类的计数:
SELECT name, SUM(bug = 0) AS failure, SUM(bug = 1) AS success FROM buggy GROUP BY name;
写法2:标准SQL兼容写法
使用CASE语句返回有效值,再用COUNT统计非空值的数量,可在所有支持SQL标准的数据库中执行:
SELECT name, COUNT(CASE WHEN bug = 0 THEN 1 END) AS failure, COUNT(CASE WHEN bug = 1 THEN 1 END) AS success FROM buggy GROUP BY name;
两种写法均会在某类别无记录时返回0,符合计数要求。
内容的提问来源于stack exchange,提问作者cankcimen
相关产品推荐
相关产品推荐

