1. 程式人生 > >SELECT列表中的標量子查詢

SELECT列表中的標量子查詢

我們講到可以將標量子查詢當成SELECT列表中的一個列,唯一的約束就是子查詢的返回值必須只有一行記錄,而且只能有一個列。看完上章的例子有的讀者可能認為標量子查詢只能返回唯一的值,其實標量子查詢完全可以返回隨當前查詢記錄而變化的值。比如下面的SQL語句可以清楚的說明這一點:


SELECT FId,FName,(SELECTMAX(FYearPublished) FROM T_Book WHERE T_Book. FCategoryId= T_Category.FId) FROM T_Category 

這個SELECT語句首先檢索FId、FName兩個欄位,而第三個欄位不是一個列二是一個子查詢。這個子查詢位於主查詢的內部,它返回一類圖書的最新出版年份。因為聚合函式僅返回一行記錄,所以這滿足標量子查詢的條件。通過WHERE語句,這個子查詢也被連線到外部的SELECT查詢語句中,因為這個連線,MAX(FYearPublished)將返回每類圖書的最新出版年份。

需要注意的是這裡的子查詢與前邊講的有所不同,前面用到的子查詢沒有依賴於外部查詢中的欄位,也就是可以直接單獨執行,而這裡的子查詢是依賴於外部查詢中的T_Category.FId欄位的,這個子查詢是無法單獨執行的,嘗試在資料庫系統中執行下面的SQL語句:


SELECTMAX(FYearPublished) FROM T_Book WHERE T_Book. FCategoryId= T_Category.FId

執行後資料庫系統會報出如下的錯誤資訊:

  • 無法繫結由多個部分組成的識別符號"T_Category.FId"。

因為這個子查詢中引用了外部查詢中的欄位。這種引用了外部查詢中欄位的子查詢被稱為相關子查詢。

執行完畢我們就能在輸出結果中看到下面的執行結果:


FId FName

1 Story 2002

2 History 2008

3 Theory 1971

4 Technology 2005

5 Art 1771

6 Philosophy 2001

下面結合執行結果來仔細分析一下這句SQL語句。首先看執行結果中的第一行,它的FId是1.子查詢通過T_Book表中的FCategoryId欄位和T_Category表中的FId連線到外部查詢。對於第一行,FId是1,因此子查詢在T_Book表中檢索FCategoryId欄位等於1的所有圖書的FYearPublished欄位的最大值;接著檢視外部查詢的第二行,FId是2,這次子查詢檢索T_Book表中FCategoryId欄位等於2的所有圖書的FYearPublished欄位的最大值;然後檢視外部查詢的第三行……以此類推。

如果沒有子查詢中的WHERE子句將子查詢連線到外部查詢,則結果將只是子查詢返回的所有記錄的最大值。比如修改上面的SQL語句,將子查詢中的WHERE 子句刪除,將得到下面的SQL語句:


SELECT FId,FName,(SELECTMAX(FYearPublished) FROM T_Book) FROM T_Category

執行這個SQL語句則會得到下面的執行結果:


FId FName

1 Story 2008

2 History 2008

3 Theory 2008

4 Technology 2008

5 Art 2008

6 Philosophy 2008

MAX(FYearPublished)現在是T_Book 表中所有記錄的最大出版年份,它不與任何書籍分類相關。