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。