嵌套查詢 一個SELECT FROM WHERE語句稱為一個查詢塊。 嵌套查詢:將一個查詢塊嵌套在另一個查詢塊的WHERE子句或者HAVING短語的條件中的查詢。 註:子查詢的SELECT語句中不能使用ORDER BY子句,ORDER BY子句只能對最終查詢結果排序。 1.帶有IN謂詞的子查詢: 子 ...
嵌套查詢
一個SELECT FROM WHERE語句稱為一個查詢塊。
嵌套查詢:將一個查詢塊嵌套在另一個查詢塊的WHERE子句或者HAVING短語的條件中的查詢。
註:子查詢的SELECT語句中不能使用ORDER BY子句,ORDER BY子句只能對最終查詢結果排序。
1.帶有IN謂詞的子查詢:
子查詢往往是一個集合。
查詢與Mike在同一個系的學生:
SELECT Sno,Sname,Sdept FROM Student WHERE Sdept IN
(SELECT Sdept FROM Student WHERE Sname='Mike');
子查詢的查詢條件不依賴於父查詢,成稱為不相關子查詢。
子查詢的查詢條件依賴於父查詢,成稱為相關子查詢。
查詢選修了DB_Design的學生學好和姓名。
SELECT Sno,Sname FROM Student WHERE Sno IN
(SELECT Sno FROM SC WHERE Cno IN
(SELECT Cno FROM Course WHERE Cname='DB_Design')
);
2.帶有比較運算符的子查詢:
當用戶確切知道內層查詢返回的是單個值時,可以用>、<、=、>=、<=、!=(<>)等比較運算符。
SELECT Sno,Sname,Sdegree FROM Student WHERE Sdegree=
(SELECT Sdegree FROM Student WHERE Sname='Mike');
SELECT Sno,Cno FROM SC x WHERE Grade>=
(SELECT AVG(Grade) FROM SC y WHERE y.Sno=x.Sno); (相關子查詢)
3.帶有ANY(SOME)或ALL謂詞的子查詢:
子查詢返回單值時可以用比較運算符,但返回多值時要用ANY(有的系統用SOME)或ALL謂詞修飾符。使用ANY或ALL也必須同時使用比較運算符。
>ANY : 大於子查詢結果中的某個值
>ALL : 大於子查詢結果中的所有值
=ANY : 等於子查詢結果中的某個值
查詢非電腦系中比電腦系任意一個學生年齡小的學生姓名和年齡。
SELECT Sname,Sage FROM Student
WHERE Sage<ANY(SELECT Sage FROM Student WHERE Sdegree='CS') AND Sdegree!='CS';
可使用聚集函數,且效率更高:
SELECT Sname,Sage FROM Student
WHERE Sage<
(SELECT MAX(Sage) FROM Student WHERE Sdegree='CS')
AND Sdegree!='CS';
4.帶有EXISTS謂詞的子查詢:
EXISTS代表存在量詞∃。帶有EXISTS謂詞的子查詢不返回任何數據,只產生邏輯值true或者false。
查詢所有選修了1001課程的學生姓名。
SELECT Sname FROM Student WHERE EXISTS
(SELECT * FROM Sc WHERE Student.Sno=Sc.Sno AND Cno='1001');
查詢沒有選修1001課程的學生姓名。
SELECT Sname FROM Student WHERE NOT EXISTS
(SELECT * FROM Sc WHERE Student.Sno=Sc.Sno AND Cno='1001');
一些帶EXISTS或NOT EXISTS謂詞的子查詢不能被其他形式的子查詢代替,但所有帶IN謂詞、比較運算符、ANY和ALL謂詞的子查詢都能用到EXISTS謂詞的子查詢代替。
SQL中沒有全稱量詞,全稱量詞用存在量詞表示。
查詢選修了全部課程的學生姓名。(有點繞)
SELECT Sname FROM Student WHERE NOT EXISTS(
SELECT * FROM Course WHERE NOT EXISTS(
SELECT * FROM Sc WHERE Student.Sno=Sc.Sno AND Course.Cno=Sc.Cno));
SQL中沒有蘊含邏輯運算 p→q=¬p∨q
查詢至少選修了學生2016002選修的全部課程的學生號碼。
SELECT DISTINCT Sno FROM SC SCX WHERE NOT EXISTS(
SELECT * FROM SC SCY WHERE SCY.Sno='2016002' AND NOT EXISTS (
SELECT * FROM SC SCZ WHERE SCZ.Sno=SCX.Sno AND SCZ.Cno=SCY.Cno));