注意:由于有人声称 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 中的值是否存在,方法是使用 IN 运算符检查来自 table_b 的值。
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
输出符合预期。现在我们将在表table_b 中插入一个null 值,并查看上述两个查询的行为。
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" 运算符。
第一个查询:
第一个查询将像这样在内部处理。所以null 不会在这里产生问题,因为我的前两个操作数将评估为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 IN 运算符时从表table_b 中选择所有not null 值。
SQL> select * from table_a where a not in (select * from table_b where b is not null);
A
----------
1
2
因此,在使用 NOT IN 运算符时,请务必注意列中的 NULL 值。
小心 NULL!!