SQL语句允许测试一个子查询的结果中是否有元组。而在这个业务逻辑中,Exists关键字起到了至关重要的作用。
- Exists的基本逻辑
Exists结构在作为参数的子查询中返回值不是为空集合时,返回true,是空集时,返回为false。同理,Not Exists结构与Exists的结构相反,返回值为空集时,返回true,为非空集合时,返回false。
使用Exists作为连接词的嵌套查询叫做相关子查询。其执行的基本逻辑是:执行查询的时候先在外层查询的一个属性值,然后执行与此属性值相关的子查询,执行完毕后,看子查询的结果返回相应的布尔值,之后,再一次取外层查询的下一个属性值,按照上面逻辑进行子查询。
比如:查询EMP表中的领导编号和姓名
select empno,ename from emp e where exists(select 1 from emp p where e.empno=p.mgr);
使用not exists结构可以模拟集合包含的运算。我们可以将“关系A包含B”写成“not exists(B minus A)"。
比如:查询使用了全部药品的医疗费用凭单编码。
--第一种方法
select distinct fyid
from detl a --1.先在这个表里去一个值
where not exists --5.只有在返回值为空集的时候才能显示结果,也就是说3中所有的ylxmbm和2中的完全一样,
--即为题目中所要求查询的使用过所有药品的fyid
(select ylxmbm
from item
where ylxmlb = '1' --3.医疗项目表里筛选出药品的ylxmbm
minus --4.取差集运算,3中的ylxmbm-2中的ylxmbm
(select ylxmbm from detl b
where a.fyid = b.fyid --2.子表和外表做一个关联,查询fyid对应的所有ylxmbm
));
--第二种方法
select distinct fyid
from detl a
where not exists (select 1
from item b
where ylxmlb='1' and
not exists (select 2
from detl c where a.fyid=c.fyid and b.ylxmbm=c. ylxmbm));
- Exists和In之间的对比
一般来说,两者是用于做多表联合查询用的,in是把外表和内表做一个Hash连接,exists是对外表做一个LOOP循环。假如现有A、B两表,使用时可以这样写:
1、select * from A where id in (select id from B)--使用in
2、select * from A where exists(select B.id from B where B.id=A.id)--使用exists也可以完全不使用in和exists:
3、select A.* from A,B where A.id=B.id--不使用in和exists
而在具体的使用过程中,我们应该选择哪一个,主要根据业务的需求进行判定。这三者之间唯一的区别在于效率不同:
第一条语句使用了A表的索引;
第二条语句使用了B表的索引;
第三条语句使用了A、B表的索引;
如果A、B表中数据不是很大,这三者执行效率几乎无差别。但是如果A表大,B表小,显然第一条语句效率更高,反之,第二条执行效率更高。而第三条语句是在同时使用A、B表的索引,在执行效率方面,是三者中最差的,因为其使用的是笛卡儿积的次数。
虽说in和exists除了在效率方面,并无太大区别,但并不代表not in 和not exists是可以相互代替的。可以看下下面例子
exists使用小结
通过业务只是通过外表来查询本表的一些数据,或者集合的包含关系,可以使用exists。