MySQL not in与not exists的区别

今天了解到mysql的not exists所以研究了一下和not in的区别和exists的具体作用。
下面是结合查询的信息和资料自己对 not exists的理解

not in 是内外表都进行全表扫描,没有用到索引(是把外表和内表作hash 连接,即将内表和外表做一个笛卡尔积,然后按照条件进行筛选)。
而not exists的子查询依然能用到表上的索引,(exists是对外表作loop循环,每次loop循环再对内表进行查询。使用exists关键字进行查询的时候,首先,我们先查询的不是子查询的内容,而是查我们的主查询的表)

exists 与 in 最大的区别在于 in引导的子句只能返回一个字段,比如:select name from student where mark in (select id,name,age from user where age>3)
in子句返回了三个字段,这是不正确的,exists子句是允许的,但in只允许有一个字段返回,即不能返回id,name,age,只能返回其中一个。
而not exists 和not in 分别是exists 和 in 的 对立面。exists (sql 返回结果集,为真)

这里着重 exists
select * from A a where not exists (select * from B b where a.id=b.id);

如上面的语句会先执行
select * from A
然后,根据表的每一条记录,执行以下语句,依次去判断where后面的条件是否成立:
select * from B b where a.id=b.id
; exists 语句中只要返回true or false就可以了,所以可以直接select id或者select 1

例子:
user表数据有:

id name
1 张三
2 李四

1、
select * from user a where not exists (select * from user b where a.id=b.id);
返回的是无结果也就是空
解析:
select * from user b where a.id=b.id 会有两条数据返回也就是user表的全部数据
当把 select * from user的结果带入进去回发现两个数据都存在也就是子查询不为空即exists都成立为true,所以a表的两条记录被排除
所以最终返回空
如果是 exists 即:
select * from user a where exists (select * from user b where a.id=b.id);
则会返回所有数据
2、
select * from user a where not exists (select * from user b where a.if=1 and a.id=b.id);
执行上面语句的时候
会返回 id=2 name 李四
解析:
当把a表查询的数据带入会发现当把李四的数据带入即
select * from user b where a.if=1 and 2=b.id时查询数据不存在也就是子查询不存在这条数据,所以exists不成立为false,这条记录not exists 时被记录出现在最终结果集中。
3、
select * from user a where not exists(select 1)
这个结果是为空无结果,因为 select 1是有数据即每个a表查询的数据带入子查询都有结果集。
select * from user a where not exists(select 1!=1)
这个结果也是为空,虽然select 1!=1返回的是0也就是false但是这是有数据的,只是子查询的结果集都为0,当把a的数据带入每个子查询都有结果集 0,所以not exist 时排除不在最终结果集

还有另一种说法可能更好理解。
exists (sql 返回结果集,为真)
主要看exists括号中的sql语句结果是否有结果,有结果:才会继续执行where条件;没结果:视为where条件不成立。
not exists (sql 不返回结果集,为真)主要看not exists括号中的sql语句是否有结果,无结果:才会继续执行where条件;有结果:视为where条件不成立.

参考:
https://blog.csdn.net/weixin_43944305/article/details/115076455
https://blog.csdn.net/weixin_34438539/article/details/113166002

你可能感兴趣的:(mysql,sql,数据库)