应优先用 COALESCE 处理 NULL:它将空值转为可控默认值,支持多参数链式 fallback,但需确保类型兼容;IFNULL 是其双参数简化版,NULLIF 用于相等时返回 NULL;聚合函数默认跳过 NULL,需用 COALESCE 显式转换以避免统计偏差;存储过程中须显式校验或兜底 NULL 参数,防止静默失效。

用 COALESCE 替代直接比较 NULL
MySQL 中 NULL 不等于任何值,包括它自己,所以 col = NULL 或 col != NULL 永远返回 FALSE。常见错误是写 WHERE status != 'done' 但漏掉 status IS NULL 的行。
健壮写法优先用 COALESCE 把空值转为可控默认值:
SELECT COALESCE(price, 0) * quantity AS total FROM orders;
多个备选时可链式 fallback:COALESCE(a, b, c, 0) 从左到右取第一个非 NULL 值。
注意:COALESCE 所有参数必须类型兼容,否则隐式转换可能出错(比如字符串和数字混用)。
IFNULL 和 NULLIF 的适用边界
IFNULL(expr1, expr2) 是 COALESCE 的双参数简化版,性能略优,但仅支持两个参数;NULLIF(a, b) 在 a = b 时返回 NULL,否则返回 a,常用于“规避除零”或“条件清空字段”:
SELECT id, NULLIF(status, 'pending') AS safe_status FROM tasks;
- 当
status = 'pending'→ 返回NULL - 其他值(含
NULL)→ 原样返回
别误用 NULLIF 判断空值:它不处理 NULL 输入的逻辑分支,NULLIF(col, NULL) 永远返回 col(因为 NULL = NULL 不成立)。
聚合函数中 NULL 的默认行为与陷阱
SUM()、AVG()、COUNT() 等天然跳过 NULL,这是合理设计,但容易引发误解:
-
COUNT(col)只统计非NULL行,COUNT(*)统计所有行 -
AVG(col)分母是COUNT(col),不是COUNT(*);若全为NULL,结果为NULL,不是0 - 想强制包含空值参与计算?先用
COALESCE转换:AVG(COALESCE(score, 0))
聚合前没清洗 NULL,可能导致业务指标偏差——比如平均分被低估(因缺考者被完全排除),而实际需要的是“全员平均(缺考记 0)”。
存储过程/函数里避免 NULL 传播中断逻辑
在自定义函数中,若参数声明为 IN 且传入 NULL,后续表达式一旦涉及 NULL 运算(如 + - * /、字符串拼接),结果大概率变 NULL,且不会报错,静默失效:
DELIMITER $$ CREATE FUNCTION calc_bonus(salary DECIMAL(10,2), rate DECIMAL(3,2)) RETURNS DECIMAL(10,2) BEGIN RETURN salary * rate; -- 若 salary 或 rate 是 NULL,结果必为 NULL END$$ DELIMITER ;
解决方法:显式校验 + 默认兜底
- 用
IFNULL(salary, 0)或COALESCE(salary, 0)强制转义 - 对关键参数加前置判断:
IF salary IS NULL THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'salary cannot be NULL';
最易忽略的是:函数返回类型声明为 NOT NULL 时,若内部逻辑返回 NULL,MySQL 不报错也不截断,而是按类型默认值填充(如数值型填 0),掩盖问题。










