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

6次阅读

不能用 == NULL 或 = NULL 判断 NULL,因为 NULL 表示未知值,所有常规比较结果均为 UNKNOWN,WHERE 只接受 TRUE;必须用 IS NULL 或 IS NOT NULL。

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

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

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

正确做法只能用 IS NULLIS NOT NULL —— 它们是专门设计用于判断 NULL 的谓词,返回布尔值 TRUEFALSE

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

它不只是写在 WHERE 里;实际开发中常出现在连接条件、聚合前过滤、以及配合 COALESCEIFNULL 做兜底。

  • 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 '
    'cannot be generated always as'' that would cause a NULL value
  • 使用 JSON_EXTRACT 从 JSON 字段取值,缺失路径返回 NULL,此时仍需用 IS NULL 判断,不能用 = 'null' —— 后者是在比字符串

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

text=ZqhQzanResources