1. 程式人生 > >SQL相關子查詢與非相關子查詢

SQL相關子查詢與非相關子查詢

SQL子查詢可以分為相關子查詢和非相關子查詢兩類。

假設Books表如下:
類編號 圖書名 出版社 價格
2 c#高階應用 聖通出版 23.00
2 Jsp開發應用 機械出版社 45.00
3 高等數學 濟南出版社 25.00
3 瘋狂英語 清華大學出版社 32.00

非相關子查詢的執行不依賴與外部的查詢。
執行過程:
(1)執行子查詢,其結果不被顯示,而是傳遞給外部查詢,作為外部查詢的條件使用。
(2)執行外部查詢,並顯示整個結果。  
非相關子查詢一般可以分為:返回單值的子查詢和返回一個列表的子查詢,
下面舉例說明:
1.返回單值: 查詢所有價格高於平均價格的圖書名,作者,出版社和價格。

SElECT 圖書名,作者,出版社,價格
  FROM Books
  WHERE 價格 >
  (
    SELECT AVG(價格)
    FROM Books
  )

2.返回值列表–查詢所有借閱圖書的讀者資訊

SElECT *
  FROM Readers
  WHERE 讀者編號 IN
  (
    SELECT 讀者編號
    FROM [Borrow History]
  )

相關子查詢的執行依賴於外部查詢。多數情況下是子查詢的WHERE子句中引用了外部查詢的表。
執行過程:
(1)從外層查詢中取出一個元組,將元組相關列的值傳給內層查詢。
(2)執行內層查詢,得到子查詢操作的值。
(3)外查詢根據子查詢返回的結果或結果集得到滿足條件的行。
(4)然後外層查詢取出下一個元組重複做步驟1-3,直到外層的元組全部處理完畢。   
下面舉例說明:
查詢Booka表中大於該類圖書價格平均值的圖書資訊SElECT 圖書名,出版社,類編號,價格

SELECT FROM Books As a
  WHERE 價格 >
  (
    SELECT AVG(價格)
    FROM Books AS b
    WHERE a.類編號=b.類編號
  )

與前面介紹過的子查詢不同,相關子查詢無法獨立於外部查詢而得到解決。該子查詢需要一個“類編號”的值。而這個值是個變數,隨SQLSever檢索Books表中的不同行而改變。下面詳細說明該查詢執行過程:
  先將Books表中的第一條記錄的“類編號”的值“2”代入子查詢中,子查詢變為:
      SELECT AVG(價格)
       FROM Books AS b
     WHERE b.類編號=2
  子查詢的結果為該類圖書的平均價格,所以外部查詢變為:
      SElECT 圖書名,出版社,類編號,價格
       FROM Books As a
     WHERE 價格 > 34
如果WHERE條件為True,則第一條結果包括在結果集中,則否不包括。對Books表中的所有行執行相同的過程,最後形成的結果集及最後返回結果。

總結
非相關子查詢是獨立於外部查詢的子查詢,子查詢總共執行一次,執行完畢後將值傳遞給外部查詢。
相關子查詢的執行依賴於外部查詢的資料,外部查詢執行一行,子查詢就執行一次。
故非相關子查詢比相關子查詢效率高。