MySQL中无IF-ELSE语句,普通SQL中必须用CASE WHEN替代:支持简单等值(CASE col WHEN 1 THEN 'a')和搜索表达式(CASE WHEN col>0 THEN 'pos')两种写法;可用于SELECT、UPDATE、INSERT...SELECT的条件赋值,但需注意NULL处理、类型一致性及索引影响。

MySQL里没有IF-ELSE语句,但可以用CASE WHEN替代
MySQL的存储过程或函数中支持IF语句,但在普通SELECT、UPDATE、INSERT ... SELECT这类上下文中,IF-ELSE不可用——必须用CASE WHEN。它不是“模拟”,而是标准SQL语法,在MySQL中完全合法且高效。
常见错误是试图在SELECT里写IF col > 0 THEN 'yes' ELSE 'no' END,这会直接报错:ERROR 1064 (42000): You have an error in your SQL syntax。正确写法只能是CASE WHEN结构。
CASE WHEN两种写法:简单比较 vs 搜索表达式
区别在于匹配逻辑:CASE col WHEN 1 THEN 'a' WHEN 2 THEN 'b'只支持等值判断;而CASE WHEN col > 0 THEN 'pos' WHEN col 支持任意布尔表达式,更常用。
- 简单形式(
CASE col WHEN ...)不能用运算符或函数,仅限=语义 - 搜索形式(
CASE WHEN expr THEN ...)可嵌套AND/OR、调用IS NULL、BETWEEN等,推荐优先使用 - 所有
WHEN子句按顺序求值,遇到第一个为TRUE的就返回对应THEN结果,后续不再执行 - 必须有
END,漏写会触发语法错误
SELECT name,
CASE WHEN score >= 90 THEN 'A'
WHEN score >= 80 THEN 'B'
WHEN score >= 70 THEN 'C'
ELSE 'F'
END AS grade
FROM students;
在UPDATE和INSERT中用CASE WHEN做条件赋值
这是最易被忽略的实用场景:避免写多个UPDATE语句,用一个语句完成多条件更新。
-
UPDATE中CASE WHEN必须出现在SET子句右侧,不能独立成行 - 每个分支的返回值类型要尽量一致,否则MySQL可能隐式转换(如把字符串转成数字),导致意外截断或警告
- 在
INSERT ... SELECT中,可对源数据做实时分类映射,比如把原始状态码转为业务标签
UPDATE orders
SET status_text = CASE WHEN status = 1 THEN 'pending'
WHEN status = 2 THEN 'shipped'
WHEN status = 3 THEN 'delivered'
ELSE 'unknown'
END;
NULL处理和性能注意事项
CASE WHEN本身不索引友好,但不会阻止整条语句使用索引——关键看WHERE条件是否能走索引。真正影响性能的是在WHEN中滥用函数,比如CASE WHEN YEAR(create_time) = 2023 THEN ...会让create_time索引失效。
-
NULL在比较中永远不等于任何值(包括NULL),所以WHEN col = NULL永远不成立;要用WHEN col IS NULL - 没有匹配到任何
WHEN时,返回ELSE值;若没写ELSE,默认返回NULL - 如果分支结果列类型差异大(如混合
VARCHAR和INT),MySQL会统一转为最高优先级类型,可能引发隐式转换警告
复杂嵌套或大量分支时,逻辑容易出错,建议先在SELECT中验证分支逻辑,再挪到UPDATE或存储过程中。


















