SQL中EXISTS的使用

Rain Man發表於2015-05-04

1.簡介

  • 不相關子查詢:子查詢的查詢條件不依賴於父查詢的稱為不相關子查詢。
  • 相關子查詢:子查詢的查詢條件依賴於外層父查詢的某個屬性值的稱為相關子查詢,帶EXISTS 的子查詢就是相關子查詢
  • EXISTS表示存在量詞:帶有EXISTS的子查詢不返回任何記錄的資料,只返回邏輯值“True”或“False”

2.表結構

選課表:學號、課程號

學生表:學號、姓名

課程表:課程號、課程名

3.查詢所有選修了“C1”課程的學生名。

普通SQL查詢:

SELECT 姓名 
FROM 學生表 
WHERE 學號 IN (SELECT 學號 FROM 選課表 WHERE 課程號 = 'C1'); 

帶EXISTS的SQL查詢:

SELECT 姓名
FROM 學生表
WHERE EXISTS    
(
    SELECT * 
    FROM 選課表
    WHERE 學生表.學號 = 選課表.學號 AND 課程號 = 'C1' 
);

相關子查詢執行過程:先在外層查詢中取“學生表”的第一行記錄,用該記錄的相關的屬性值(在內層WHERE子句中給定的)處理內層查詢,若外層的WHERE子句返回“TRUE”值,則這條記錄放入結果表中。然後再取下一行記錄;重複上述過程直到外層表的記錄全部遍歷一次為止。

EXISTS語句不關心子查詢的具體內容,因此用“SELECT *”,“Exists + 子查詢”用來判斷該子查詢是否返回記錄。

  • Exists:若子查詢的結果集非空時,返回“True”;若子查詢的結果集為空時,返回“False” 。
  • NOT EXISTS :若子查詢結果為空,返回“TRUE”值;若子查詢的結果集非空時,返回 “FALSE。

4.查詢沒有選C1課程的學生的學號、姓名

SELECT 姓名
FROM 學生表
WHERE NOT EXISTS
(
    SELECT *
    FROM 選課表
    WHERE 學生表.學號 = 選課表.學號 AND 課程號 = 'C1'
);

5.查詢選修了所有課程的學生的姓名(續)

SELECT 姓名
FROM 學生表
WHERE NOT EXISTS
(
    SELECT *
    FROM 課程表
    WHERE NOT EXISTS
    (
       SELECT *
       FROM 選課表
       WHERE 學生表.學號 = 選課表.學號 AND 課程表.課程號 = 選課表.課程號
    )
);

6.查詢至少選修了S1所選的全部課程的學生名

SELECT 姓名
FROM 學生表
WHERE NOT EXISTS                     
( 
    SELECT *
    FROM 選課表 AS 選課表X            
    WHERE 選課表X.學號='s1' AND NOT EXISTS            
    (
        SELECT *
        FROM 選課表 AS 選課表Y
        WHERE  學生表.學號 = 選課表Y.學號 AND 選課表X.課程號 = 選課表Y.課程號
    )
);

7.在FROM語句中使用子查詢,對查詢結果定義表名及列名 例:求平均成績超過80分的學號及平均成績

SELECT 學號, AVG_G
FROM        
(
    SELECT 學號, AVG(Grade)
    FROM 選課表
    GROUP BY 學號 
) AS RA(學號, AVG_G)
WHERE AVG_G > 80 

相關文章