七、SQL-子查詢⑤(標量子查詢where)

先看一個簡單的例子

例:要檢索喜歡“Story”的讀者主鍵列表,(可以使用連接來完成,但使用子查詢的實現思路也比使用連接簡單)使用子查詢來完成。

1、首先肯定要到T_Category 表中查找FName等于“Story”的記錄的FId字段值:

SELECT FId FROM T_Category WHERE FName=" Story "

因為這個查詢的返回值是單列且單行的,所以可以當作標量子查詢使用。
2、然后,將這個子查詢結果來構造外部查詢:

SELECT FReaderId FROM T_ReaderFavorite 
WHERE FCategoryId=(SELECT FId FROM T_Category WHERE FName="Story")

執行結果:

FReaderId
1
6
7
12
3

再看一個復雜點的例子

例:假設需要檢索每一種書籍類別中出版年份最早的書籍的名稱,如果有兩本或者多本書籍在同一年出版,則均顯示它們的名字。要求檢索結果中顯示出類型的名字、書的名字和它的出版年份。

檢索每種類型圖書中出版時間最早的圖書非常簡單,只要使用GROUP BY 子句以及聚合函數就可以輕松完成這個任務,SQL語句如下:

SELECT T_Category.FId,MIN(T_Book.FYearPublished)
FROM T_Category INNER JOIN T_Book ON
T_Category.FId=T_Book.FCategoryId GROUP BY T_Category.FId

執行結果:

FId
1 1999
2 1700
3 1930
4 2003
5 1771
6 1995

查詢結果是正確的,不過這個查詢結果沒有提供書名,嘗試將圖書的名字加入到SELECT語句中,如下:

SELECT T_Category.FId, T_Book. FName,MIN(T_Book.FYearPublished) 
FROM T_Category INNER JOIN T_Book ON T_Category.FId=T_Book.FCategoryId GROUP BY T_Category.FId

執行該SQL語句會提示錯誤信息:
選擇列表中的列"T_Book.FName" 無效,因為該列沒有包含在聚合函數或GROUP BY子句中。

錯誤原因: 所有在SELECT列表中的字段如果沒有包含在聚合函數中,則必須放到GROUP BY 子句中,所以將T_Book. FName加入到GROUP BY 子句中,修改后的SQL語句如下:

SELECT T_Category.FId, T_Book. FName,MIN(T_Book.FYearPublished) 
FROM T_Category INNER JOIN T_Book ON T_Category.FId=T_Book.FCategoryId GROUP BY T_Category.FId, T_Book. FName

執行結果:

FId FName
1 Jane Eyre 2001
1 Oliver Twist 2002
1 Two Cites 1999
2 History of America 1700
2 History of China 1982
2 History of England 1860
2 History of TheWorld 2008
3 Astronomy 1971
3 Atom 1930
3 Computer 1970
3 RELATIVITY 1945
4 About J2EE 2005
4 Learning Hibernate 2003
5 How To Singing 1771
6 DaoDeJing 2001
6 Obedience to Authority 1995

這個執行結果顯然是錯誤的,因為它們是根據T_Category.FId和T_Book.FName這兩個字段進行的分組,所以MIN(T_Book.FYearPublished)返回值不是一個特定書籍類型的最早出版年份,而是每本圖書中的最早出版年份。

而真正需要的是:查詢每種書籍類型中的最早出版的書籍,可以使用子查詢來輕松完成這個任務。在SQL查詢中,需要將一本書籍的出版年份與該類型的所有書籍的出版年份進行比較,并且僅僅在它們匹配時,才返回一個記錄,實現SQL語句如下:

SELECT T_Category.FId, T_Book. FName,T_Book.FYearPublished 
FROM T_Category INNER JOIN T_Book ON T_Category.FId=T_Book.FCategoryId 
WHERE T_Book.FYearPublished=(SELECT MIN(T_Book.FYearPublished) 
FROM T_Book WHERE T_Book.FCategoryId=T_Category.FId)

在這個SQL語句中:
首先T_Category表和T_Book表進行內部連接,然后使用WHERE子句中使用子查詢來進行數據的過濾。
這個子查詢是一個相關子查詢,它返回外部查詢中當前圖書類別中的圖書的最早出版年份。在外部查詢的WHERE子句中,T_Book的FYearPublished與子查詢的返回值進行比較,這樣就可以得到每種書籍類型中的出版最早的書籍了。

執行結果:

FId FName FYearPublished
1 Two Cites 1999
2 History of America 1700
3 Atom 1930
4 Learning Hibernate 2003
5 How To Singing 1771
6 Obedience to Authority 1995

在where語句中,子查詢是使用最多的一種之一。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。