Oracle 子查詢(復雜select語句)


  在執行數據操作時,如果某個操作需要依賴於另外一個 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 語句的關聯子查詢。

 


免責聲明!

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



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