case when 在 select 中必须写 else,否则空值或异常值变 null 导致前端空白、统计失真;where 中慎用以防索引失效;聚合时 count 忽略 null 而 sum 需显式 else 0;order by 中可用但避免函数调用。

SELECT 中用 CASE WHEN 做字段映射必须写 ELSE
漏掉 ELSE 会导致本该有业务含义的空值或异常值变成 NULL,前端渲染为空白、报表统计失真、下游系统解析失败。比如用户等级按积分分档:CASE WHEN amount >= 5000 THEN 'VIP' WHEN amount >= 1000 THEN 'Gold' END —— 所有 amount 为 NULL 或 ≤ 0 的记录全变成 NULL,而不是“无效”或“未激活”。
实操建议:
• 只要分支不能穷举所有可能(含 NULL、负数、空字符串等),就加 ELSE
• ELSE 后别写 NULL,优先用业务可读值,如 ELSE '其他'、ELSE 0、ELSE '待确认'
• 简单等值匹配可用简写形式:CASE status WHEN 'A' THEN '激活' WHEN 'I' THEN '禁用' ELSE '未知' END
WHERE 里嵌套 CASE WHEN 容易让索引失效
想用 CASE WHEN 实现“角色是 admin 就不限制权限,否则只查公开数据”,写成 WHERE CASE WHEN @role = 'admin' THEN 1 ELSE is_public END = 1 看似简洁,但数据库优化器通常无法对该表达式做索引下推,执行计划大概率走全表扫描。
实操建议:
• 过滤逻辑尽量拆成 OR/AND 组合:WHERE (@role = 'admin') OR (is_public = 1)
• 真需动态条件,优先在应用层拼 SQL,或用存储过程分支(如 SQL Server 的 IF、MySQL 的 PREPARE)
• CASE WHEN 只适合出现在 SELECT、ORDER BY、HAVING,WHERE 中慎用
聚合统计时 COUNT 和 SUM 对 ELSE 的处理完全不同
用 CASE WHEN 配合聚合函数统计分组指标是最常见也最容易错的地方。比如统计“已支付订单金额总和”:SUM(CASE WHEN status = 'paid' THEN amount END) —— 这里没写 ELSE,结果是 NULL;而 SUM(CASE WHEN status = 'paid' THEN amount ELSE 0 END) 才能确保返回数字。
实操建议:
• 计数用 COUNT(CASE WHEN condition THEN 1 END),别写 ELSE 0(COUNT 忽略 NULL,但会把 0 当作有效行计)
• 求和用 SUM(CASE WHEN condition THEN amount ELSE 0 END),ELSE 0 必须显式写,否则整列结果可能为 NULL
• 分类统计多个指标时,每个 CASE 独立写,不要共用一个表达式
ORDER BY 里用 CASE WHEN 自定义排序顺序
状态字段按“待处理→处理中→已完成”这种非字典序排列,CASE WHEN 是标准解法,且只要 status 字段有索引,数据库仍可能利用索引优化排序。
实操建议:
• 写法示例:ORDER BY CASE status WHEN 'pending' THEN 1 WHEN 'processing' THEN 2 WHEN 'done' THEN 3 ELSE 4 END
• 避免在 CASE 中调用函数(如 UPPER(status)),否则索引失效
• 如果该排序逻辑高频复用,考虑建计算列(如 status_sort_order TINYINT)并单独索引,比每次查询都算更稳定










