You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何含NULL值的IN操作子句可正常运行?技术咨询

为什么IN操作子句包含NULL值不会报错?

这问题问得特别好!其实核心原因和SQL的三值逻辑以及IN操作符的具体行为有关,咱们慢慢理清楚:

首先纠正一个常见误解:IN ≠ 多个OR加field=NULL

你以为IN等价于field=val1 OR field=val2 OR ... OR field=NULL,但这里有个关键区别:在SQL里,field=NULL这个表达式永远返回UNKNOWN(既不是TRUE也不是FALSE),而IN操作符处理NULL的逻辑是专门设计过的——它不会直接用=去匹配NULL,而是遵循三值逻辑判断,但这只是影响查询结果,并不会触发语法错误。

SQL语法允许IN列表包含NULL,这是合法写法

数据库引擎不会把IN子句里的NULL当成错误,因为SQL标准明确允许这种用法。报错通常只会发生在语法错误(比如括号不匹配、字段名拼写错误)或者执行错误(比如权限不足、表不存在)的场景,而IN里放NULL属于完全合规的语法,所以根本不会报错。

举个实际例子更清楚

假设你的employee表有这些数据:

emp_idsuperior_emp_id
1NULL
21
32

如果执行:

SELECT * FROM employee WHERE superior_emp_id IN (2, NULL);
  • emp_id=3的superior_emp_id是2,和列表里的2匹配,返回TRUE,所以会被选中;
  • emp_id=1的superior_emp_id是NULL,这时候IN会先检查是否等于2(结果是FALSE),再判断是否匹配列表里的NULL——这时候结果是UNKNOWN,而WHERE子句只会保留结果为TRUE的行,所以这行不会被选中;
  • emp_id=2的superior_emp_id是1,和列表里的两个值都不匹配,结果是FALSE,也不会被选中。

如果换成你直觉里的等价写法:

SELECT * FROM employee WHERE superior_emp_id=2 OR superior_emp_id=NULL;

结果和上面的IN查询完全一样——因为superior_emp_id=NULL永远是UNKNOWN,所以emp_id=1还是不会被选中。而如果想要正确匹配NULL,得用superior_emp_id IS NULL:

SELECT * FROM employee WHERE superior_emp_id=2 OR superior_emp_id IS NULL;

这时候emp_id=1和3都会被选中,这才是你想要的“包含NULL”的效果。

最后总结一下

IN子句里包含NULL不会报错,是因为这是SQL允许的合法语法,只是它的逻辑结果和你预想的OR field=NULL不一样(毕竟=NULL本身就不是正确的NULL判断方式),但语法上完全合规,所以数据库只会按照三值逻辑返回结果,不会抛出错误。

内容的提问来源于stack exchange,提问作者Robert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:35:12