注意:由于有人声称Sushant Butta的答案中的外部链接已失效,因此我将内容作为单独的答案发布在此处。
当心NULLS。
今天,我在使用IN和NOT IN
运算符时遇到了一个非常奇怪的查询行为。实际上,我想比较两个表,找出是否table b
存在from的值,table a
如果列包含null
值,则找出其行为。因此,我刚刚创建了一个环境来测试此行为。
我们将创建表table_a
。
SQL> create table table_a ( a number);
Table created.
我们将创建表table_b
。
SQL> create table table_b ( b number);
Table created.
将一些值插入table_a
。
SQL> insert into table_a values (1);
1 row created.
SQL> insert into table_a values (2);
1 row created.
SQL> insert into table_a values (3);
1 row created.
将一些值插入table_b
。
SQL> insert into table_b values(4);
1 row created.
SQL> insert into table_b values(3);
1 row created.
现在,我们将执行查询以table_a
通过table_b
使用IN
操作符检查值的存在来检查值的存在。
SQL> select * from table_a where a in (select * from table_b);
A
3
执行以下查询以检查不存在。
SQL> select * from table_a where a not in (select * from table_b);
A
1
2
输出达到预期。现在,我们将null
在表中插入一个值,table_b
并查看上述两个查询的行为。
SQL> insert into table_b values(null);
1 row created.
SQL> select * from table_a where a in (select * from table_b);
A
3
SQL> select * from table_a where a not in (select * from table_b);
no rows selected
第一个查询的行为符合预期,但是第二个查询发生了什么?为什么我们没有得到任何输出,应该怎么办?查询有什么区别吗?没有。
变化在表的数据中table_b
。我们null
在表中引入了一个值。但是,它的行为方式如何呢?让我们将两个查询拆分为"AND"
和"OR"
运算符。
第一个查询:
第一个查询将在内部进行类似这样的处理。因此,anull
不会在这里造成问题,因为我的前两个操作数将等于true
或false
。但是我的第三个操作数a = null
将不会true
求和false
。它将评估为null
。
select * from table_a whara a = 3 or a = 4 or a = null;
a = 3 is either true or false
a = 4 is either true or false
a = null is null
第二个查询:
第二个查询将按以下方式处理。由于我们使用的是"AND"
运算符,因此任何true
操作数以外的任何东西都不会给我任何输出。
select * from table_a whara a <> 3 and a <> 4 and a <> null;
a <> 3 is either true or false
a <> 4 is either true or false
a <> null is null
那么我们该如何处理呢?我们将在使用运算符时not null
从表中选择所有值。table_b
NOT IN
SQL> select * from table_a where a not in (select * from table_b where b is not null);
A
1
2
因此NULL
,在使用NOT IN
运算符时,请务必注意列中的值。
当心NULL!
in
语句将与解析相同field=val1 or field=val2 or field=val3
。在其中放置一个null将归结为field=null
无效。