Oracle基礎之exists解讀

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。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章