not in
和 not exists
在 Oracle 查询中有什么区别?
何时使用 not in
,何时使用 not exist
?
NOT IN 和 NOT EXISTS 的区别在于结果中包含 NULL
值时会更加明显。
例如:
create table test_a (col1 varchar2(30 char));
create table test_b (col1 varchar2(30 char));
insert into test_a (col1) values ('a');
insert into test_a (col1) values ('b');
insert into test_a (col1) values ('c');
insert into test_a (col1) values ('d');
insert into test_a (col1) values ('e');
insert into test_b (col1) values ('a');
insert into test_b (col1) values ('b');
insert into test_b (col1) values ('c');
insert into test_b (col1) values (null);
请注意:关键区别在于test_b
包含了一个 null
值。
select * from test_a where col1 not in (select col1 from test_b);
没有返回任何行
select * from test_a where
not exists
(select 1 from test_b where test_b.col1 = test_a.col1);
返回
col1
====
d
e
exists更快,但是性能会有所不同。
最重要的区别在于对null值的处理。你可能会认为使用in和exists查询结果相同,但是当子查询返回null时,你可能会感到惊讶。
你可能会发现存在null值会导致exists查询失败。
请参考Joe Celko的《SQL for smarties》以获得更好的解释何时使用每个查询方式。
Not in 是用于在一组元素中测试元素的存在性,因此更简单。
Not exists 可以处理更复杂的查询,包括分组(例如具有 sum(x)=z 或具有 count(*)>3 的情况),具有多个条件的结果(例如匹配多个元素),并且可以利用索引。
在某些情况下,not in 比 not exists 更容易实现。我通常发现这是在测试一组值中键字段的值时。
作为经验法则,我更喜欢使用 not exists,因为它涵盖了比 not in 更多的情况。Not exists 可以用于 not in 适用的每种情况,但反之则不行。