SQL如何查询空值或非空值_IS NULL与IS NOT NULL判断

2次阅读

WHERE子句中column = NULL查不到数据,因为NULL是缺失值标记而非值,=比较返回UNKNOWN而非TRUE,WHERE只保留TRUE结果;正确写法是WHERE column IS NULL。

SQL如何查询空值或非空值_IS NULL与IS NOT NULL判断

WHERE子句里写 column = NULL 为什么查不到数据?

因为 sqlNULL 不是值,而是“缺失值”的标记,它不等于任何东西——包括它自己。所以用 =!= 判断 NULL 全部返回 UNKNOWN,而 WHERE 只认 TRUE,直接过滤掉。

  • 错误写法:WHERE name = NULL(永远不匹配)
  • 正确写法:WHERE name IS NULL
  • 同理,WHERE name != NULLWHERE name NULL 也无效,必须用 IS NOT NULL
  • 注意:部分数据库(如 postgresql)支持 IS DISTINCT FROM,能安全比较含 NULL 的表达式,但标准写法仍是 IS NULL/IS NOT NULL

字符串字段为空字符串 ''NULL 是两回事

空字符串是明确的、长度为 0 的字符串值;NULL 表示该字段根本没有值。很多业务逻辑会把这两者混为一谈,但 SQL 默认不自动等价处理。

  • 要同时查出 NULL 和空字符串:WHERE name IS NULL OR name = ''
  • 想统一视为空(比如清洗数据时):WHERE COALESCE(name, '') = ''COALESCE 返回第一个非 NULL 值)
  • mysql 有个陷阱:'' 在某些排序或索引场景下可能被当作 NULL 处理(尤其在 utf8mb4 + COLLATE utf8mb4_0900_as_cs 下),但判断逻辑不变——仍需显式写 = ''IS NULL

IS NULL 能用上索引吗?

可以,但取决于索引类型和数据库实现。B-tree 索引默认不存储全 NULL 键(PostgreSQL 除外,默认存;MySQL InnoDB 则只在联合索引中存 NULL,单列索引不存)。

  • 单列索引上 WHERE status IS NULL 在 MySQL 中通常走不了索引(除非是覆盖索引或启用了 innodb_use_null 相关优化)
  • 联合索引如 (user_id, status)WHERE user_id = 123 AND status IS NULL 很可能走索引
  • 更可靠的方式:给常查 NULL 的字段建函数索引(如 PostgreSQL 的 CREATE INDEX ON t ((status IS NULL)))或加一个计算列(如 MySQL 5.7+ 的虚拟列)
  • 别依赖 EXPLAIN 里显示 key 就一定高效——要看 rows 和实际执行时间

聚合函数里 NULL 怎么算?

几乎所有聚合函数(countSUMAVGMAXMIN)默认忽略 NULL,但 COUNT(*) 是例外:它统计所有行,不管字段是否为 NULL

  • COUNT(col):只统计 col IS NOT NULL 的行
  • COUNT(*):统计整行,哪怕所有字段都是 NULL 也算 1
  • SUM(col) 返回 NULL 当且仅当所有 col 都是 NULL;只要有一个非 NULL 值,就正常求和
  • 想把 NULL 当 0 加进去?用 SUM(COALESCE(col, 0))

真正容易漏的是:前端传参时把空字符串当 NULL 插入,或者 ORM 自动生成的 WHERE 条件没区分 is null== ''。查不到数据时,先 select <em> FROM t WHERE col IS NULL LIMIT 5</em>SELECT FROM t WHERE col = '' LIMIT 5 分开看一眼,比翻文档快。

text=ZqhQzanResources