CASE WHEN是标准SQL条件表达式,非转向语句,支持SELECT、WHERE、ORDER BY等位置;分简单形式(CASE column WHEN value THEN...)仅等值判断,和搜索形式(CASE WHEN condition THEN...)支持任意布尔表达式,各分支返回值类型须一致。

CASE WHEN 不是“转向语句”,它是标准 SQL 的条件表达式,用于在 SELECT、WHERE、ORDER BY 等位置动态生成值。 直接写 CASE WHEN 就行,不需要额外声明或开启功能——所有主流数据库(PostgreSQL、MySQL 5.7+、SQL Server、Oracle、SQLite)都原生支持。
怎么写最简 CASE WHEN(简单形式)
当判断字段是否等于某些固定值时,用 CASE column WHEN value THEN ... 更简洁,但只支持等值判断,不支持 >、IS NULL、LIKE 等。
- 适用于:分类字段映射,比如把
status数字转成中文描述 - 不能写:
WHEN status > 0或WHEN status IS NULL—— 会报错 - 示例:
SELECT name, CASE level WHEN 1 THEN '初级' WHEN 2 THEN '中级' ELSE '高级' END AS level_text FROM users;
怎么写搜索 CASE WHEN(搜索形式)
真正灵活的写法是 CASE WHEN condition THEN ...,每条 WHEN 后跟完整布尔表达式,顺序执行、命中即停。
- 这是实际项目里 90% 的使用场景,比如按金额分档、多条件组合判断
- 注意:
ELSE不写默认为NULL,线上查询易引发空值逻辑错误,建议显式写ELSE '未知' - 性能提示:条件越靠前,越可能被提前命中;把高频分支放前面
- 示例:
SELECT order_id, amount, CASE WHEN amount >= 1000 THEN '大单' WHEN amount >= 100 THEN '中单' WHEN amount > 0 THEN '小单' ELSE '无效订单' END AS order_type FROM orders;
CASE WHEN 能用在哪些地方(不只是 SELECT)
它本质是个“表达式”,只要 SQL 允许放表达式的地方,就能用 CASE WHEN。
-
WHERE中做动态过滤:WHERE CASE WHEN type = 'A' THEN status IN (1,2) ELSE status = 3 END(慎用,可读性差,优先拆成 OR) -
ORDER BY中自定义排序逻辑:ORDER BY CASE WHEN is_pinned = 1 THEN 0 ELSE 1 END, created_at DESC -
GROUP BY中构造分组维度:GROUP BY CASE WHEN score >= 60 THEN 'pass' ELSE 'fail' END - 聚合函数内嵌套:
AVG(CASE WHEN paid = true THEN amount END)—— 注意这里ELSE隐含NULL,AVG会自动忽略
容易踩的坑:NULL 和类型隐式转换
CASE WHEN 所有 THEN 和 ELSE 分支返回值必须兼容同一数据类型,否则数据库会尝试隐式转换,结果可能出人意料。
- 常见翻车点:混用字符串和数字,比如
THEN 'N/A'和ELSE 0→ PostgreSQL 报错,MySQL 可能转成'0'字符串 -
NULL在WHEN条件中要小心:WHEN col = NULL永远不成立,得写WHEN col IS NULL - 嵌套过深难维护:超过 4 层
CASE建议抽到视图或应用层处理 - MySQL 8.0+ 支持
COALESCE(CASE ..., NULL)简化写法,但别为了省字符牺牲可读性
真正麻烦的不是语法,而是当业务规则变复杂(比如“VIP 用户在节假日下单满减”这种多维交叉逻辑)时,CASE WHEN 很快变成难以验证的面条代码。这时候该考虑把规则外移到配置表或应用层了。

















