1.介绍
exists和in都有过滤功能,他俩最大的差别就是in引导的子句只能对一个字段进行限制,比如
但是如果我们想对多个字段进行限制,使用in就不合适了,例如
此时就可以使用exists 来对多个字段进行限制了
select * from A where exists (select 1 from B where A.sid=B.sid and A.tid=B.tid)
EXISTS 语法理解为:将主查询的数据放在子查询中做条件验证,根据结果TRUE 和 FALSE 来决定主查询中的数据是否需要保留。EXISTS 子查询只返回TRUE 或 FALSE ,因此子查询中的SELECT * 可以是SELECT 1 或者其他,MySql 的官方说在实际执行时会忽略SELECT 清单,因此是没有 什么区别的。EXISTS 子查询其实在执行时,MySql 已经对它做了一些优化并不是对每条数据进行对比。
2.原理
exists做为where条件时,是先对where 前的主查询询进行查询,然后用主查询的结果一个一个的代入exists的查询进行判断,如果为真则输出当前这一条主查询的结果,否则不输出。
select * from A where exists (select 1 from B where A.sid=B.sid and A.tid=B.tid)
它先执行A表的查询,再将查询结果一条一条放到B表的条件中去查询,如果存在,则显示此条
select * from A where exists (select * from B where B.id=‘条件‘)
在这种情况下,只要子查询的条件成立,就会查询出表1中的所有记录,反之,如果子查询中没有查询到记录,则表1不会查询出任何的记录。
以上两种方式本质上都是对A表查询进行过滤
3.select 1 from table;
select 1 from table;
select anycol(anycol代表目的表集合中的任意一个列属性)from table;
select * from table ;
从作用上来说是没有差别的,都是查看是否有记录,一般是作条件查询用的。select 1 from 中的1是一常量(可以为任意数值),查到的所有行的值都是它,但从效率上来说,1>anycol>*,因为不用查字典表。
在Sql中 常常和exists和no exists结合着用,exists/no exists就是判断是否有结果,并不关心结果的内容,所以select 后面的字段都无所谓,只要越快越好
F:select * from tab1 where not exists (select 1 from tab2 where tab1.col=tab2.col)
3.实例
表A
ID NAME
1 A1
2 A2
3 A3
表B
ID AID NAME
1 1 B1
2 2 B2
3 2 B3
表A和表B是1对多的关系 A.ID => B.AID
1.SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE A.ID = B.AID);
执行结果:
ID NAME
1 A1
2 A2
原理如下:
(1)SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID=1)
---> SELECT * FROM B WHERE B.AID=1有值,返回真,所以有数据
(2)SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID=2)
---> SELECT * FROM B WHERE B.AID=2有值,返回真,所以有数据
(3)SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID=3)
---> SELECT * FROM B WHERE B.AID=3无值,返回假,所以没有数据
得到的结果为,A.ID=1或2时才有数据,所以最终的条件等于
SELECT ID,NAME FROM A where id in (1,2);
exists