为何not in的筛选条件中不可以存在空值

开发工具与关键技术:Oracle sql*plus 、 PLSQL Developer
作者:吴晓佩
撰写时间:2019年4月6日

上次我在子查询中用多行操作符(not in)进行数据查询时出现过此种情况,数据是空的,为了验证一下结果,我用in 查询了该表的数据,发现查询出来的结果数据并没有等于该表的总数据,所以not in一定是会存在数据的,然而数据竟然是null。

原因是条件中存在一个空值,我刚开始知道查询的数据里存在空值,但是没有去在意,因为按我们正常的思维来想不等于空值也用该是可行的才对的(刷掉字段不在这里面的数据,空值也可以理解为不是空值的,而我需要的数据里面也本就不应该存在空值的),下面就是有空值与去掉空值查询出来的结果。

图(1)子查询中存在空值,查询结果没有数据。
为何not in的筛选条件中不可以存在空值
图(1)

图(2)利用where过滤掉空值,查询出如下数据。
为何not in的筛选条件中不可以存在空值
图(2)
in理解:例如department_id in (123,99,null)我们可以看作是(department_id =123 or department_id=99 or department_id=null)把department_id满足此处任一条件的数据都查询出来。

Not in 理解:基于in的理解, department_id in (123,99,null)即可看作是not(department_id =123 or department_id=99 or department_id=null),满足括号的所有条件, 进一步理解为(department_id !=123 and department_id!=99 and department_id!=null) 而department_id!=null一直会是等于false,所以查询出来的数据是空值。

所以我们在用not in进行数据过滤的时候一定要注意空值,无论你查询出来的数据中是否存在空值,都最好用is not null来处理一下,如图(2)。