SQL 中 CASE WHEN 用法全面详解
CASE WHEN 是 SQL 中非常强大的条件判断表达式,类似于编程语言中的 if-else 或 switch 语句。它可以根据条件返回不同的值,常用于数据转换、分组统计、动态排序等场景。
SQL 中有两种 CASE 语法:
1. 简单 CASE(类似 switch)
CASE 表达式
WHEN 值1 THEN 结果1
WHEN 值2 THEN 结果2
...
ELSE 默认结果
END
2. 搜索 CASE(更常用,类似 if-elseif-else)
CASE
WHEN 条件1 THEN 结果1
WHEN 条件2 THEN 结果2
...
ELSE 默认结果
END
注意:END 是必须的!否则报错。ELSE 可省略,省略时相当于 ELSE NULL。
一、基本用法示例
假设有表 students:
| id | name | score |
|---|---|---|
| 1 | 张三 | 85 |
| 2 | 李四 | 62 |
| 3 | 王五 | 95 |
| 4 | 赵六 | 45 |
| 5 | null | null |
示例1:根据分数划分等级(搜索 CASE,最常用)
SELECT
name,
score,
CASE
WHEN score >= 90 THEN '优秀'
WHEN score >= 80 THEN '良好'
WHEN score >= 60 THEN '及格'
ELSE '不及格'
END AS grade
FROM students;
结果:
| name | score | grade |
|---|---|---|
| 张三 | 85 | 良好 |
| 李四 | 62 | 及格 |
| 王五 | 95 | 优秀 |
| 赵六 | 45 | 不及格 |
| null | null | 不及格(因为 NULL 不满足任何条件) |
示例2:简单 CASE(匹配具体值)
SELECT
name,
score,
CASE score
WHEN 100 THEN '满分'
WHEN 0 THEN '零分'
ELSE '普通分数'
END AS remark
FROM students;
示例3:处理 NULL 值
SELECT
name,
CASE
WHEN score IS NULL THEN '未考试'
WHEN score >= 60 THEN '通过'
ELSE '未通过'
END AS status
FROM students;
示例4:在 ORDER BY 中动态排序(超级实用!)
-- 优先让 score=100 的排最前,其余按 score 降序
SELECT name, score
FROM students
ORDER BY
CASE WHEN score = 100 THEN 0 ELSE 1 END, -- 100分排前面
score DESC;
示例5:在 UPDATE 中使用(修改数据)
UPDATE students
SET grade = CASE
WHEN score >= 90 THEN 'A'
WHEN score >= 80 THEN 'B'
WHEN score >= 60 THEN 'C'
ELSE 'F'
END;
示例6:结合聚合函数统计(分组统计神器)
SELECT
CASE
WHEN score >= 90 THEN '优秀'
WHEN score >= 60 THEN '及格'
ELSE '不及格'
END AS level,
COUNT(*) AS count,
AVG(score) AS avg_score
FROM students
GROUP BY
CASE
WHEN score >= 90 THEN '优秀'
WHEN score >= 60 THEN '及格'
ELSE '不及格'
END;
结果示例:
| level | count | avg_score |
|---|---|---|
| 优秀 | 1 | 95.0 |
| 良好 | 1 | 85.0 |
| 及格 | 1 | 62.0 |
| 不及格 | 1 | 45.0 |
示例7:多条件组合(AND/OR)
CASE
WHEN score >= 90 AND name LIKE '张%' THEN '优秀且姓张'
WHEN score >= 80 OR score IS NULL THEN '良好或未考'
ELSE '其他'
END
示例8:嵌套 CASE(不推荐过多嵌套,可读性差)
CASE
WHEN score IS NULL THEN '未考'
ELSE
CASE
WHEN score >= 90 THEN '优秀'
ELSE '非优秀'
END
END
二、常见注意事项
| 注意点 | 说明 |
|---|---|
| 类型一致 | 所有 THEN 和 ELSE 的结果类型必须一致(都是字符串或数字) |
| NULL 判断 | 用 IS NULL / IS NOT NULL,不能用 = NULL |
| 条件执行顺序 | 从上到下,满足第一个条件就返回,后面的不再判断 |
| 可在 SELECT/WHERE/GROUP BY/ORDER BY/HAVING 中使用 | 全方位可用 |
| MySQL 支持在 WHERE 中直接用 CASE | 但建议逻辑放 SELECT 中更清晰 |
| 性能 | 过多复杂 CASE 可能影响性能,必要时考虑建视图或存储过程 |
三、实际应用场景总结
| 场景 | 推荐用法 |
|---|---|
| 数据清洗/转换 | 将代码转为可读文字(如 status 1→’启用’) |
| 动态分组统计 | 按条件分组 COUNT/SUM/AVG |
| 自定义排序规则 | ORDER BY CASE … |
| 报表字段生成 | 生成“等级”“是否达标”等衍生列 |
| 权限控制展示 | 根据角色显示不同内容 |
掌握 CASE WHEN 后,你的 SQL 查询能力会提升一个大台阶!它几乎是写复杂报表和数据分析 SQL 的必备武器。
如果你有具体业务场景(如“如何用 CASE WHEN 实现 pivot 表格”或“多表联查中的条件判断”),欢迎继续提问,我可以给出针对性示例!