mysql中NULL值的判断与IS NULL操作使用

来源:这里教程网 时间:2026-02-28 20:40:54 作者:

为什么不能用
== NULL
= NULL
判断 NULL?

因为 SQL 中的

NULL
表示“未知值”,不是某个具体值,所有与
NULL
的常规比较(
=
!=
>=
等)结果都是
UNKNOWN
,而
WHERE
子句只接受
TRUE
的行。所以
WHERE col = NULL
永远不匹配任何行,哪怕该列全是
NULL

正确做法只能用

IS NULL
IS NOT NULL
—— 它们是专门设计用于判断
NULL
的谓词,返回布尔值
TRUE
FALSE

IS NULL
在 WHERE、JOIN 和函数中的典型用法

它不只是写在

WHERE
里;实际开发中常出现在连接条件、聚合前过滤、以及配合
COALESCE
IFNULL
做兜底。

WHERE
中过滤空值:
SELECT * FROM users WHERE email IS NULL;
LEFT JOIN
后识别“没匹配到”的记录:
SELECT u.name, o.order_id FROM users u LEFT JOIN orders o ON u.id = o.user_id WHERE o.user_id IS NULL;
COALESCE
配合提供默认值:
SELECT COALESCE(phone, '未填写') AS contact FROM customers;
(注意:这里不用
IS NULL
,但逻辑上依赖对
NULL
的识别)

容易踩的坑:NULL 在聚合、索引和 ORDER BY 中的行为

IS NULL
本身没问题,但后续操作如果没意识到
NULL
的特殊性,就会出错。

COUNT(col)
自动忽略
NULL
,而
COUNT(*)
统计所有行 —— 别误以为两者等价
普通 B+ 树索引默认不存储全为
NULL
的键(除非是唯一索引且允许一个
NULL
),所以
WHERE col IS NULL
可能走不了索引,需确认执行计划:
EXPLAIN SELECT * FROM logs WHERE status IS NULL;
ORDER BY col ASC
时,
NULL
默认排最前;
DESC
时也排最前(不是最后),如需调整顺序,得显式写
ORDER BY col IS NULL, col ASC

MySQL 8.0+ 对 NULL 的增强:隐藏列与生成列中的 NULL 处理

在定义生成列(generated column)或使用不可见列(invisible column)时,表达式若产生

NULL
,会直接存入,但约束行为更严格:

生成列为
STORED
且定义了
NOT NULL
,但表达式结果为
NULL
,插入会报错:
ERROR 1151 (HY000): Column '<col>' cannot be generated always as '<expr>' that would cause a NULL value</expr>
使用
JSON_EXTRACT
从 JSON 字段取值,缺失路径返回
NULL
,此时仍需用
IS NULL
判断,不能用
= 'null'
—— 后者是在比字符串

真正麻烦的从来不是怎么写

IS NULL
,而是忘记它只解决“是否为空”这一步;后续的业务逻辑、索引策略、排序需求,都得跟着重新评估一遍。

相关推荐