在執行數據操作時,如果某個操作需要依賴於另外一個 select語句的查詢結果,那么就可以把 select 語句遷入到該操作語句中,這樣就形成了一個子查詢。實際應用中,表與表之間相互關聯,相互依存,這樣就可以根據數據之間的關系使用相應的子查詢,從而實現復雜的查詢。
一、子查詢
子查詢是在 SQL 語句內的另外一條 select 語句,也被稱為內查詢或是 內select語句。在select、insert、update 或delete 命令中允許是一個表達式的地方都可以包含子查詢,子查詢也可以包含在另外一個子查詢里面中。
EG:
SQL > select empno,ename,job from emp
where deptno = (select deptno from dept where dname="research");
表示在emp表中查詢部門名稱為(dname)為“research” 的員工信息。
分析:原來在 emp 表中不存在 dname 字段,但 emp 表中存在 depno字段(部門代碼);dname 字段原本存在 dept 表中,並且 deptno 字段也存在 dept表中,所有 deptno 為兩個表之間的關聯字段,這樣就可以通過多表關聯查詢來實現。等同於下面的多表查詢:
SQL > select empno,ename,job from emp join dept on emp.deptno = dept.deptno
where dept.dname = 'research';
從上可以看出,相比於多表關聯查詢,子查詢更加靈活、功能更強大,而且更容易理解。但是多表關聯查詢的效率要高於子查詢。
在執行子查詢操作的語句中,子查詢也稱為內查詢,包含子查詢的查詢語句也被稱為外查詢或主查詢。
在執行查詢時,外查詢語句檢索一行,子查詢語句需要檢索一遍數據,然后判斷外查詢語句的條件是否滿足。如果滿足,則外查詢語句將檢索到數據行添加到結果集中,如果條件不滿足,則外查詢語句繼續檢索下一行數據,所有子查詢相對多表關聯查詢要慢。
注意:
- 子查詢語句必須用括號 "()" 括起來。
- 子查詢中不能包括 order by 子句。
- 子查詢運行嵌套多層,但不能超過255層。
二、單行子查詢
單行子查詢是指返回一行數據的子查詢語句。當在 where 子句中引用單行子查詢時,可以使用當行比較運算符(=、>、<、>=、<=和<>)。
EG:
SQL > select empno,ename,sal from emp
where sal > (select min(sal) from emp) and sal < (select max(sal) from emp);
注意:
- 內層子查詢的執行結果如果為空值,那么外層的 where 子句就始終不會滿足條件,這樣的查詢結果就必然為空值
- 執行單行子查詢時,要注意子查詢的返回結果必須是一行數據,否則 Oracle 系統會提示無法執行。
- 子查詢中不能包含 order by 子句,如果非要進行排序的話,那么只能在外查詢語句中使用 order by 子句。
三、多行子查詢
多行子查詢是指返回多行數據的子查詢語句。當在 where 子句中使用多行子查詢時,必須使用多行運算符(in、any、all)。
1、使用 in 運算符
當在多行子查詢中使用 in 運算符時,外查詢會嘗試與子查詢結果中的任何一個結果進行匹配,只要有一個匹配成功,則外查詢返回當前檢索的記錄。
EG:
SQL > select empno,ename,job
from emp where deptno in
(select deptno from dept where dname<>'sales');
2、使用 any 運算符
any 運算符必須與單行比較運算符結合使用,並且返回行只要匹配子查詢的任何一個結果即可。
EG:
SQL > select deptno,ename,sal from emp where sal > any
(select sal from emp where deptno = 10) and deptno <> 10;
表示從emp表中,查詢工資大於部門編號為10的任意一個員工工資即可的其他部門的員工信息。
3、使用 all 運算符
all 運算符必須與單行運算符結合使用,並且返回行必須匹配所有子查詢結果。
EG:
SQL > select deptno,ename,sal from emp where sal > all
(select sal from emp where deptno = 30);
表示從emp表中,查詢工資大於部門編號為 30 的所有員工工資的員工信息。
四、關聯子查詢
在單行子查詢和多行子查詢中,內查詢和外查詢是分開執行的,也就是說內查詢的執行與外查詢的執行時沒有關系的,外查詢僅僅是使用內查詢的最終結果。在一些特殊需求的子查詢中,內查詢的執行需要借助於外查詢,而外查詢的執行又離不開內查詢的執行,這時,內查詢和外查詢是相互關聯的,這種子查詢就被稱為關聯子查詢。
EG:
SQL > select empno,ename,sal from emp f
where sal > (select avg(sal) from emp where job = f.job)
order by job;
表示在emp表中,使用“關聯子查詢”檢索工資大於同職位的平均工資的員工信息。
注意:
- 在執行關聯子查詢的過程中,必須遍歷數據表中的每條記錄,因此如果被遍歷的數據表中有大量的數據記錄,則關聯子查詢的執行速度會比較慢。
- 關聯字查詢不僅僅可以作為 select 語句的子查詢,也可以作為 insert 、 update或 delete 語句的關聯子查詢。