注意:由于有人声称Sushant Butta 的答案中的外部链接已失效,因此我已将内容作为单独的答案发布在这里。
当心NULLS。
今天我在使用 IN 和运算符时遇到了一个非常奇怪的查询行为NOT IN
。实际上,我想比较两个表并找出其中是否table b
存在值,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 的数据中table_b
。我们null
在表中引入了一个值。但它怎么会这样呢?让我们将两个查询拆分为"AND"
and"OR"
运算符。
第一个查询:
第一个查询将在内部处理,如下所示。所以 anull
不会在这里产生问题,因为我的前两个操作数将评估为true
or 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
。
谨防空!!