SQL中的NULL陷阱:为何=永远查不到空值

在 SQL 的三值逻辑里,NULL 表示"未知值",任何与未知值的比较结果仍然是未知(UNKNOWN),而查询只保留结果为 TRUE 的行,因此 =、<、>、LIKE 等常规运算符"遇 NULL 就消失",永远得不到 TRUE。


  1. 三值逻辑(TRUE / FALSE / UNKNOWN)

SQL 的布尔体系不是二值,而是三值:

表达式 结果 说明
5 = 5 TRUE 确定相等
5 = 6 FALSE 确定不等
5 = NULL UNKNOWN 不知道 5 与"未知"是否相等
NULL = NULL UNKNOWN 两个未知值是否相等?仍是未知
NULL LIKE '%x' UNKNOWN 同样未知
NULL > 3 UNKNOWN 未知值与 3 的大小关系未知

WHERE 子句只保留 TRUE 的行;UNKNOWN 被当作 FALSE 丢弃。

因此

sql 复制代码
SELECT ... WHERE col = NULL

永远返回 0 行,因为没有任何行能使条件为 TRUE。


  1. 为什么 "=" 不能替代 IS NULL

"=" 是普通比较运算符,遵循上面的三值逻辑。

IS NULL 是 SQL 提供的特殊谓词 ,它直接检查"是否为缺失值" ,返回 TRUE 或 FALSE,不会产生 UNKNOWN

换句话说:

表达式 结果
col IS NULL TRUE 或 FALSE
col = NULL 永远是 UNKNOWN → 被过滤掉

因此

sql 复制代码
WHERE col = NULL        -- 语法合法,但逻辑错误

不会报错,也永远查不到数据。


  1. 为什么 LIKE、>、<、<> 同样失效

它们都是比较类运算符,只要操作符两边出现 NULL,结果就退化为 UNKNOWN,于是行被丢弃。

例子:

sql 复制代码
-- 假设 tel 里有 NULL 值
WHERE tel LIKE '%5'   -- NULL LIKE '%5'  → UNKNOWN  → 被过滤
WHERE tel > '700'     -- NULL > '700'   → UNKNOWN  → 被过滤

  1. 唯一正确的做法

  • 判断是 NULL:

    sql 复制代码
    WHERE col IS NULL
  • 判断非 NULL:

    sql 复制代码
    WHERE col IS NOT NULL

  1. 小结口诀

"NULL 遇运算符,结果全失踪;
想抓 NULL,只能用 IS,不能用 =。
"

相关推荐
win x1 天前
JavaSE(基础)高频面试点及 知识点
java·面试·职场和发展
Terio_my1 天前
简要 Java 面试题学习
java·开发语言·学习
熊猫钓鱼>_>1 天前
动态网站发布部署核心问题详解
前端·nginx·容器化·网页开发·云服务器·静态部署
方也_arkling1 天前
elementPlus按需导入配置
前端·javascript·vue.js
踢足球09291 天前
寒假打卡:2026-01-31
数据库·sql
好好研究1 天前
Spring Boot - Thymeleaf模板引擎
java·spring boot·后端·thymeleaf
爬山算法1 天前
Hibernate(76)如何在混合持久化环境中使用Hibernate?
java·后端·hibernate
编程彩机1 天前
互联网大厂Java面试:从分布式缓存到消息队列的技术场景解析
java·redis·面试·kafka·消息队列·微服务架构·分布式缓存
我的xiaodoujiao1 天前
使用 Python 语言 从 0 到 1 搭建完整 Web UI自动化测试学习系列 44--将自动化测试结果自动推送至钉钉工作群聊
前端·python·测试工具·ui·pytest
她说..1 天前
策略模式+工厂模式实现单接口适配多审核节点
java·spring boot·后端·spring·简单工厂模式·策略模式