case when 本身不能单独完成行列转换,必须配合 group by 和聚合函数(如 sum、max)才能生效;漏掉任一环节会导致报错、多行重复或整列 null,因其仅是表达式,不改变非分组属性,压缩多行为单行须依赖聚合函数实现。

直接说结论:CASE WHEN 本身不能单独完成行列转换,必须配合 GROUP BY 和聚合函数(如 SUM、MAX)才能生效。漏掉任一环节,要么报错,要么结果为空或错乱。
为什么单独写 CASE WHEN 会出错?
常见错误现象是:ERROR 1055 (45000): Expression #2 of SELECT list is not in GROUP BY clause 或返回多行重复、值为 NULL。
原因很实在:SQL 标准规定,SELECT 中非 GROUP BY 字段,必须被聚合函数包裹。而 CASE WHEN 只是表达式,不改变字段的“非分组属性”。
- 没加
GROUP BY→ 每条原始记录都输出一行,CASE WHEN只在对应行生效,其他列为NULL - 加了
GROUP BY但没套聚合函数 → 数据库拒绝执行(MySQL 5.7+ 默认严格模式) - 用了
MIN/MAX却忽略ELSE→ 空值参与比较,可能让整列变NULL
CASE WHEN + SUM 和 MAX 的区别在哪?
关键看数据是否允许重复、是否需要容错:
-
SUM(CASE WHEN ... THEN value END):适合数值累加场景(如销售额、订单量),NULL自动忽略,结果为0或实际和 -
MAX(CASE WHEN ... THEN value END):适合取唯一值场景(如姓名、科目成绩),只要有一行匹配,就取该值;多行匹配时取最大值(注意:字符串按字典序) - 两者都建议显式写
ELSE 0或ELSE NULL,避免隐式类型转换干扰
示例:同一学生同一科目有多条成绩记录,用 MAX 更合理;若要统计总分,则必须用 SUM。
MySQL 中容易被忽略的 NULL 处理细节
MySQL 对 NULL 的聚合行为和别的数据库略有不同,尤其影响 CASE WHEN 输出:
-
CASE WHEN month = 'jan' THEN revenue END→ 不写ELSE时,默认补NULL -
SUM(...)遇到全NULL返回NULL,不是0;想强制为0得写COALESCE(SUM(...), 0) -
MAX(...)同样返回NULL(而非报错),但很多 BI 工具会把NULL渲染为空白,造成“数据消失”假象 - 别依赖
IFNULL包裹整个CASE,应优先在CASE内部写ELSE 0
真正卡住人的地方,往往不是语法写不对,而是没意识到 CASE WHEN 的输出是“每行一个值”,而行列转换本质是“把多行压缩成一行”——这个压缩动作,只能靠聚合函数完成。漏掉它,就像只画了半张弓,拉不开箭。










