在SQL語言中,一個 SELECT-FROM-WHERE 語句稱爲一個查詢塊。將一個查詢塊嵌套在另外一個查詢塊的 WHERE 子句或 HAVING 短語的條件中的查詢稱爲 嵌套查詢。例如:函數
SELECT Sname /*外層查詢或父查詢*/ FROM Student WHERE Sno IN (SELECT Sno /*內層查詢或子查詢*/ FROM SC WHERE Cno='2');
SQL語言容許多層嵌套查詢,即一個子查詢中還能夠嵌套其餘子查詢。學習
注意:子查詢的SELECT語句中不能使用 ORDER BY 子句,由於 ORDER BY 子句只能對最終查詢結果排序。spa
在嵌套查詢中,子查詢的結果每每是一個集合,因此謂詞 IN 是嵌套查詢中最常常使用的謂詞。code
查詢與「劉晨」在同一個系學習的學生blog
SELECT Sno,Sname,Sdept FROM Student WHERE Sdept IN (SELECT Sdept FROM Student WHERE Sname='劉晨');
查詢選修了課程名爲「信息系統」的學生學號和姓名排序
SELECT Sno,Sname /*最後在Student關係中取出Sno和Sname*/ FROM Student WHERE Sno IN (SELECT Sno /*而後在SC關係中找出選修了3號課程的學生學號*/ FROM SC WHERE Cno IN (SELECT Cno /*首先在Course關係中找出「信息系統」的課程號,結果爲3號*/ FROM Course WHERE Cname='信息系統' ) );
本查詢一樣能夠用鏈接查詢實現:table
SELECT Student.Sno,Sname FROM Student,SC,Course WHERE Student.Sno=SC.Sno AND SC.Cno=Course.Cno AND Course.Cname='信息系統';
帶有比較運算符的子查詢是指父查詢與子查詢之間用比較運算符進行鏈接。當用戶能確切知道內層查詢返回的是單個值時,能夠用 >、<、=、>=、<=、!=、或<>等比較運算符。class
找出每一個學生超過他本身選修課程平均成績的課程號計算機科學
SELECT Sno,Cno FROM SC X WHERE Grade >=(SELECT AVG(Grade) FROM SC y WHERE y.Sno=x.Sno);
子查詢返回單值時能夠用比較運算符,但返回多值時要用ANY(有的系統用SOME)或ALL謂詞修飾符。而使用ANY或ALL謂詞時則必須同時使用比較運算符。其語義以下:程序
>ANY |
大於子查詢結果中的某個值 |
>ALL |
大於子查詢結果中的全部值 |
<ANY |
小於子查詢結果中的某個值 |
<ALL |
小於子查詢結果中的全部值 |
>=ANY |
大於等於子查詢結果中的某個值 |
>=ALL |
大於等於子查詢結果中的全部值 |
<=ALL |
小於等於子查詢結果中的全部值 |
<=ANY |
大於等於子查詢結果中的某個值 |
=ANY |
等於子查詢結果中的某個值 |
=ALL |
等於子查詢結果中的全部值(一般沒有實際意義) |
!=(或<>)ANY |
不等於子查詢結果中的某個值 |
!=(或<>)ALL |
不等於子查詢結果中的任何一個值 |
查詢非計算機科學系中比計算機科學系任意一個學生年齡小的學生姓名和年齡
SELECT Sname,Sage FROM Student WHERE Sage<ANY (SELECT Sage FROM Student WHERE Sdept='CS') AND Sdept <> 'CS';
查詢非計算機科學系中比計算機科學系全部學生年齡都小的學生姓名和年齡
SELECT Sname,Sage FROM Student WHERE Sage<ALL (SELECT Sage FROM Student WHERE Sdept='CS') AND Sdept <> 'CS';
提示:本查詢一樣能夠用彙集函數實現
SELECT Sname,Sage FROM Student WHERE Sage < (SELECT MIN(Sage) FROM Student WHERE Sdept='CS') AND Sdept <>'CS';
帶有EXISTS 謂詞的子查詢不返回任何數據,只產生邏輯真值「true」或邏輯假值「false」。
查詢全部選修了1號課程的學生姓名
SELECT Sname FROM Student WHERE EXISTS (SELECT * FROM SC WHERE Sno=Student.Sno AND Cno='1');
使用存在量詞EXISTS後,若內層查詢結果爲空,則外層的WHERE子句返回真值,不然返回假值。
查詢沒有選修1號課程的學生姓名
SELECT Sname FROM Student WHERE NOT EXISTS (SELECT * FROM SC WHERE Sno=Student.Sno AND Cno='1');
查詢選修了所有課程的學生姓名
因爲沒有全稱量詞,可將題目的意思轉換成等價的用存在量詞的形式:查詢這樣的學生,沒有一門課程是他不選修的。
SELECT Sname FROM Student WHERE NOT EXISTS (SELECT * FROM Course WHERE NOT EXISTS (SELECT * FROM SC WHERE Sno=Student.Sno AND Cno=Course.Cno));
查詢至少選修了學生201215122選修的所有課程的學生號碼
SELECT DISTINCT Sno FROM SC SCX WHERE NOT EXISTS (SELECT * FROM SC SCY WHERE SCY.Sno='201215122' AND NOT EXISTS (SELECT * FROM SC SCZ WHERE SCZ.Sno=SCX.Sno AND SCZ.Cno=SCY.Cno));
這次學習和整理了有關SQL與嵌套查詢相關的程序
尤爲應格外重視 ANY、ALL與彙集函數的對應關係,還有帶EXISTS時邏輯上的判斷。