oracle 子查詢詳解 in和exists的區別


sql允許多層嵌套,子查詢是嵌套在其他查詢中的查詢。我們可以把子查詢當做一張表來看到,即外層語句可以把內嵌的查詢結果當做一張表使用。

子查詢查詢結果有三種情況

不返回查詢記錄。若子查詢不返回記錄則主查詢也不會有查詢記錄

查詢單行記錄。若子查詢返回的是單行記錄,則在主查詢中可以對該單行記錄使用比較運算符

查詢多行記錄。若子查詢返回多行記錄,則在主查詢中不能對該子查詢記錄使用比較運算符

 

條件比較
=,!=,<>,<,>,<=,>=,
any,some,all
is null,is not null
between x and y
in(list),not in(list)
exists(sub-query)
like _ ,%,escape ‘\‘ _\% escape ‘\’

 

子查詢常用方法

1、any 即任何一個 ,大都用大於或小於的時候

select * from emp e where e.sal > any(1000,2000,3000);  --大於其中其中任何一個

select * from emp e where e.sal > any(select s.losal from salgrade s );--大於其中其中任何一個

2、some 一些,和any的用法相同,不過some大都用在 等於的時候

select * from emp e where e.sal = some(1000,2000,3000);--等於其中其中任何一個

select * from emp e where e.sal = some(select s.losal from salgrade s );--等於其中其中任何一個

3、all 所有,即同時滿足所有的

select * from emp e where e.sal > all(1000,2000,3000);--同時大於所有的

select * from emp e where e.sal > all(select s.losal from salgrade s );--同時大於所有的

4、in

select * from emp e where e.deptno in (10,20);

等同於  select * from emp e where e.deptno='10' or e.deptno='20';

所以當主表查詢數據量大,子查詢數據量少的情況使用in

5、exists 

exists(sub-query 只要這里面能返回一條結果,整個表達式就為true)

select e1.* from emp e1  where  exists( select 1 from dept d1 where (d1.deptno=10 or d1.deptno=20) and d1.deptno=e1.deptno);

當主查詢數據量小,子查詢數據量大的情況使用exists

 

In和exists的區別

執行效率上的比較
比如Select * from T1 where x in ( select y from T2 )
執行的過程相當於:
select * 
  from t1, ( select distinct y from t2 ) t2
 where t1.x = t2.y1 or  t1.x = t2.y2 ....;
所以當子查詢數據量較大時執行效率會降低

select * from t1 where exists ( select null from t2 where y = x )
執行的過程相當於:
for x in ( select * from t1 )
   loop
      if ( exists ( select null from t2 where y = x.x )
      then 
         OUTPUT THE RECORD
      end if
end loop
表 T1 不可避免的要被完全掃描一遍

in 是把外表和內表作hash join,而exists是對外表作loop,每次loop再對內表進行查詢。

 

如果子查詢得出的結果集記錄較少,主查詢中的表較大且又有索引時應該用in,反之如果外層的主查詢記錄較少,子查詢中的表大,又有索引時使用exists。 其實我們區分in和exists主要是造成了驅動順序的改變(這是性能變化的關鍵),如果是exists,那么以外層表為驅動表,先被訪問,如果是IN,那么先執行子查詢,所以我們會以驅動表的快速返回為目標,那么就會考慮到索引及結果集的關系了 另外IN是不對NULL進行處理

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM