sql嵌套查詢


嵌套查詢概述

一個 SELECT-FROM-WHERE 語句稱為一個查詢塊,將一個查詢塊嵌套在另一個查詢塊的 WHERE 子句 或 HAVING 短語的條件中的查詢稱為嵌套查詢

不相關子查詢

子查詢的查詢條件不依賴父查詢

相關子查詢

子查詢的查詢條件依賴父查詢

帶有IN謂詞的子查詢

查詢與“張三”在同一個系學習的學生

  1. 確定“張三”所在的系

    SELECT Sdept
    FROM student
    WHERE Sname='張三';
    

    結果為"CS"

  2. 查詢"CS"系的所有學生

    SELECT Sno, Sname, Sdept
    FROM student
    WHERE Sdept='CS';
    

    image-20220217133731474

  3. 將1的查詢嵌套進2的查詢中

    SELECT Sno, Sname, Sdept
    FROM student
    WHERE Sdept IN (
    	SELECT Sdept
    	FROM student
    	WHERE Sname='張三'
    );
    

    image-20220217133856095

  4. 用自身連接查詢實現

    /*查詢與“張三”在同一個系學習的學生學號和姓名*/
    SELECT second.Sno, second.Sname, second.`Sdept`
    FROM student FIRST, student SECOND
    WHERE first.`Sname`='張三' AND first.`Sdept`=second.`Sdept`;
    

    image-20220217135745661

查詢選修了課程名為“信息系統”的學生學號和姓名

  1. 在Course表中找“信息系統”課程的課程號

    SELECT Cno
    FROM course
    WHERE Cname='信息系統';
    

    結果為3

  2. 在SC表中找選修了3號課程的學生的學號

    SELECT Sno 
    FROM sc
    WHERE Cno='3';
    

    結果為200215121和200215122

  3. 最后在Student表中取出學號和姓名

    SELECT Sno, Sname
    FROM student
    WHERE Sno='200215121' OR Sno='200215122';
    

    image-20220217134701751

  4. 將上面三個操作嵌套

    /*查詢選修了課程名為“信息系統”的學生學號和姓名*/
    SELECT Sno, Sname
    FROM student
    WHERE Sno IN(
    	SELECT Sno
    	FROM sc
    	WHERE Cno IN(
    		SELECT Cno
    		FROM course
    		WHERE Cname='信息系統'
    	)
    );
    

    image-20220217134829457

  5. 用連接查詢實現

    /*查詢選修了課程名為“信息系統”的學生學號和姓名*/
    SELECT student.`Sno`, student.`Sname`
    FROM student, sc, course
    WHERE Cname='信息系統' AND course.`Cno`=sc.`Cno` AND sc.`Sno`=student.`Sno`;
    

    image-20220217135023178

帶有比較運算的子查詢

  • 當能確切知道內層查詢返回單值時,可用比較運 算符( > , < , = , >= , <= , != 或 < > )
  • 與 ANY 或 ALL 謂詞配合使用

假設一個學生只可能在一個系學習,並且必須屬於一個系,可以用 = 代替 IN

查詢與“張三”在同一個系學習的學生

用 = 替代謂詞 IN

/*查詢與“張三”在同一個系學習的學生學號和姓名*/
SELECT Sno, Sname, Sdept
FROM student
WHERE Sdept = (
	SELECT Sdept
	FROM student
	WHERE Sname='張三'
);

image-20220217140129193

找出每個學生超過他選修課程平均成績的課程號

SELECT Sno, Cno
FROM sc X
WHERE Grade > (
	SELECT AVG(Grade)
	FROM sc Y
	WHERE y.`Sno`=x.`Sno`
);

image-20220217140539013

此例為相關子查詢,外層查詢取出sc的一個元組x,將x.Sno(如:200215121)傳遞給內層查詢,內層查詢相當於

SELECT AVG(Grade)
FROM sc
WHERE y.`Sno`='200215121';

因此內層查詢計算得學號為200215121學生得平均成績,並將其返回給外層查詢(假定為88),則外層查詢相當於

SELECT Sno, Cno
FROM sc X
WHERE Grade > 88;

帶有ANY或ALL謂詞的子查詢

ANY:任意一個值

ALL:所有值

查詢其他系中比計算機科學某一學生年齡小的學生姓名和年齡

關鍵詞:某一

SELECT Sname, Sage
FROM student
WHERE Sdept!='CS' AND Sage<ANY(
	SELECT Sage
	FROM student
	WHERE Sdept='CS'
);

image-20220217141332234

先處理子查詢,CS系所有學生的年齡構成一個集合,再處理父查詢,找出所有不是CS系且年齡小於20或19的學生,相當於使用聚集函數MAX

SELECT Sname, Sage
FROM student
WHERE Sdept!='CS' AND Sage<(
	SELECT MAX(Sage)
	FROM student
	WHERE Sdept='CS'
);

image-20220217142429434

查詢其他系中比計算機科學系所有學生年齡都小的學生姓名及年齡

關鍵詞:所有

SELECT Sname, Sage
FROM student
WHERE Sdept!='CS' AND Sage<ALL(
	SELECT Sage
	FROM student
	WHERE Sdept='CS'
);

image-20220217142652577

相當於使用聚集函數MIN

SELECT Sname, Sage
FROM student
WHERE Sdept!='CS' AND Sage<(
	SELECT MIN(Sage)
	FROM student
	WHERE Sdept='CS'
);

image-20220217142734044

帶有EXISTS謂詞的子查詢

帶有 EXISTS 謂詞的子查詢不返回任何數據,只產生邏輯真 值“ true” 或邏輯假值“ false”

  • 若內層查詢結果非空,則外層的 WHERE 子句返回真值

  • 若內層查詢結果為空,則外層的 WHERE 子句返回假值

查詢所有選修了 1 號課程的學生姓名

SELECT Sname
FROM student
WHERE EXISTS (
	SELECT *
	FROM sc
	WHERE sc.`Cno`='1' AND sc.`Sno`=student.`Sno`
);

image-20220217143131707

依次取出student中每個元組的Sno值,用此值去檢查sc關系,若sc中存在這樣的元組,其Sno為外層查詢的Sno,且Cno為1,則取Sname送入結果集

用連接查詢實現

/*查詢所有選修了 1 號課程的學生姓名*/
SELECT Sname
FROM student, sc
WHERE sc.`Cno`='1' AND student.`Sno`=sc.`Sno`;

image-20220217143419140

查詢沒有選修 1 號課程的學生姓名

SELECT Sname
FROM student
WHERE NOT EXISTS (
	SELECT *
	FROM sc
	WHERE sc.`Cno`='1' AND sc.`Sno`=student.`Sno`
);

image-20220217143529855


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM