前言
最近写SQL的时候要求在排除A表中所存在的B表的某些同属性值的记录。
然后就想到了in和exist,但是其实一直都没有真正的去弄懂两者不同,
于是在网上查询了一些大佬的文章,然后去实践了一番,最后做一个总结
开始啰
1,建表初始化
-------------------------------------
create table a1(c1 int,c2 int);
create table a2(c1 int,c2 int);
create table a3(c1 int,c2 int);
-------------------------------------
insert into a1 values(1,NULL);
insert into a1 values(1,2);
insert into a1 values(1,3);
--------------------------------------
insert into a2 values(1,NULL);
insert into a2 values(1,2);
insert into a2 values(2,1);
--------------------------------------
insert into a3 values(1,2);
insert into a3 values(2,1);
2,执行语句
select * from a1 where c2 in (NULL)
select * from a1 where c2 not in (NULL)
--注意: in 后面的查询值不能为null,否则会出现逻辑异常,结果为无
3,时间效率比较
同大小表
select * from a1 where c2 in (select c2 from a2);
select * from a1 where exists (select c2 from a2 where a2.c2=a1.c2)
在使用 exist 和 in 分别查询两个同大小的表的时候,查询结果是没有什么差异的,查询速率明显exist更优。
select * from a1 where c2 not in (select c2 from a2);
select * from a1 where not exists (select c2 from a2 where a2.c2=a1.c2)
在使用 not exist 和 not in 分别查询两个同大小的表的时候,查询结果出现差异,not in存在逻辑错误,查询速率明显not exist更优。
一大一小表
– 子查询为小表
select * from a1 where c2 in (select c2 from a3);
select * from a1 where exists (select c2 from a3 where a3.c2=a1.c2)
当子查询表为小表时,结果无差异,exists更优
select * from a1 where c2 not in (select c2 from a3);
select * from a1 where not exists (select c2 from a3 where a3.c2=a1.c2)
当子查询表为小表时,结果有差异,not in有逻辑错误
– 子查询为大表
select * from a3 where c2 in (select c2 from a2);
select * from a3 where exists (select c2 from a2 where a2.c2=a3.c2)
**当子查询为大表,结果无差异,in更优
select * from a3 where c2 not in (select c2 from a2);
select * from a3 where not exists (select c2 from a2 where a2.c2=a3.c2)
**当子查询为大表,子查询表中该查询元素无null值时,结果无差异,not exists更优
总结:
1,如果子查询元素中有null值,不能使用not in查询
2,一般查询中,使用exists查询效率更优
4,参考链接