Oracle 子查询
子查詢可以返回單行結果,可以返回多行結果,也可以不返回結果。
?
如果子查詢未返回任何行,則主查詢也不會返回任何結果
(空值)select * from emp where sal > (select sal from emp where empno = 8888);
?
如果子查詢返回單行結果,則為單行子查詢,可以在主查
詢中對其使用相應的單行記錄比較運算符
(正常)select * from emp where sal > (select sal from emp where empno = 7566);
?
如果子查詢返回多行結果,則為多行子查詢,此時不允許
對其使用單行記錄比較運算符
(多值)select * from emp where sal > (select avg(sal) from emp group by deptno);//非法
?
子查詢中常用方法
1。any即任何一個。如果在where條件中加入>any,意思是大于任何一個,也就是大于最小的
select * from emp t
where t.sal>
any(select sal from hhgy.emp where deptno=30)
?
2。some即一些。和any的用法基本相同。用any的地方都可以用some代替。不過some大多用在=操作中。表示等于所選集合中的任何一個。當然any也可以用于=操作中,效果和some相同。
select * from emp t
where t.sal=
some(select sal from hhgy.emp where deptno=30)
?
3。all即所有。如果在where條件中加入>all,意思是大于每一個,也就是大于最大的。
select * from emp t
where t.sal>
all(select sal from hhgy.emp where deptno=30)
?
4。In
select * from emp t
where t.deptno in(30,40)
?
5。exists
select * from hhgy.emp where exists(select * from hhgy.emp where deptno=30)
?
如果子查詢得出的結果集記錄較少,主查詢中的表較大且又有索引時應該用in,反之如果外層的主查詢記錄較少,子查詢中的表大,又有索引時使用exists。 其實我們區分in和exists主要是造成了驅動順序的改變(這是性能變化的關鍵),如果是exists,那么以外層表為驅動表,先被訪問,如果是IN,那么先執行子查詢,所以我們會以驅動表的快速返回為目標,那么就會考慮到索引及結果集的關系了 另外IN是不對NULL進行處理
如:
select 1 from dual where null in (0,1,2,null)
為空
?
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.y;
相對的
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再對內表進行查詢。
?
例如:表A(小表),表B(大表)
1:
select * from A where cc in (select cc from B)
效率低,用到了A表上cc列的索引;
select * from A where exists(select cc from B where cc=A.cc)
效率高,用到了B表上cc列的索引。
相反的
2:
select * from B where cc in (select cc from A)
效率高,用到了B表上cc列的索引;
select * from B where exists(select cc from A where cc=B.cc)
效率低,用到了A表上cc列的索引。
from?http://www.cnblogs.com/Johnny_Z/archive/2010/11/07/1870939.html
帶in的關聯子查詢是多余的,因為in子句和子查詢中相關的操作的功能是一樣的。如:
select staff_name from staff_member where staff_id in
(select staff_id from staff_func where staff_member.staff_id=staff_func.staff_id);
為非關聯子查詢指定exists子句是不適當的,因為這樣會產生笛卡乘積。如:?
select staff_name from staff_member where staff_id?
exists (select staff_id from staff_func);
not in?和not exists
如果查詢語句使用了not in 那么內外表都進行全表掃描,沒有用到索引;
而not extsts 的子查詢依然能用到表上的索引。
所以無論哪個表大,用not exists都比not in要快。
盡量不要使用not in子句。使用minus 子句都比not in 子句快,雖然使用minus子句要進行兩次查詢:?
select staff_name from staff_member where staff_id in (select staff_id from staff_member minus select staff_id from staff_func where func_id like '81%');
in?與 "=" 的區別
select name from student where name in ('zhang','wang','li','zhao');
與
select name from student where name='zhang' or name='li' or name='wang' or name='zhao'
的結果是相同的。
轉載于:https://my.oschina.net/liangzhenghui/blog/484846
總結
以上是生活随笔為你收集整理的Oracle 子查询的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python项目之当当网
- 下一篇: 分别用函数和带参的宏,从三个数中找出最大