SqlServer:子查詢


子查詢

子查詢是嵌套的 SELECT 查詢,也就是就是在某個 SELECT 結果集中進行檢索。子查詢能夠將比較復雜的查詢分解為幾個簡單的查詢,而且子查詢可以嵌套。嵌套查詢時先執行內部檢查再執行外部查詢,內部查詢的結果將傳遞給外層語句,並作為外層語句的查詢條件來使用。需要指出子查詢是多表查詢的特殊情況,並不能替代多表查詢。

子查詢語法

任何允許使用表達式的地方都可以使用子查詢,使用子查詢的 SELECT 語句的一般格式如下。

SELECT 列名列表
FROM 表名1
WHERE 列名1 運算符
(
    SELECT 列名1
    FROM 表名2
    WHERE 列名2 運算符
    (
        SELECT 列名2
        FROM 表名3
        WHERE 條件
    )
)

查詢樣例

樣例一

假設 Student 表中有如下一些數據:

查詢與“王麗娜”同班的學生學號、姓名,可以在 WHERE 使用子查詢查出班級作為過濾條件。

SELECT SNO, Sname FROM Student
WHERE CLASS = (SELECT CLASS FROM Student WHERE SNAME = '王麗娜')

樣例二

查詢和學號為 101 的同學同月出生的所有學生的 Sno、Sname 和列,使用子查詢查出月份作為過濾條件。

SELECT Sno, Sname, Sbirthday FROM Student
WHERE MONTH(Sbirthday) = (SELECT MONTH(Sbirthday) FROM Student WHERE Sno = '101')

樣例三

查詢每人的成績(學號、課程號、成績)和本課程平均分,本課程平均分可以用和自己連接的子查詢查出。

SELECT Sno, Cno, Degree,
       (SELECT AVG(Degree) FROM Score sc2 WHERE sc1.Cno = sc2.Cno) 科平均
FROM Score sc1

樣例四

假設此時有成績表 Course,表中具有以下字段和記錄。

查詢每人的成績(學號、姓名、課程名、成績)和本班本科平均分,本班本科平均分可以用子查詢實現。

SELECT SC.Sno, S.Sname, SC.Cno, C.Cname, SC.Degree,
       (
           SELECT AVG(Degree) 
           FROM Score SC2 
	   JOIN Student S2 ON SC2.Sno = S2.Sno
	   JOIN Course C2 ON SC2.Cno = C2.Cno
	   WHERE S.Sname = S2.Sname AND SC.Cno = C2.Cno 
	) 班科平均
FROM Score SC
JOIN Student S ON SC.Sno = S.Sno
JOIN Course C ON SC.Cno = C.Cno

EXISTS 嵌套子查詢

EXISTS 子句

EXISTS 和 NOT EXISTS 子句通常和相關子查詢一起使用,可以限制外層查詢,使其結果集符合子查詢的條件,並可以判斷某個值是否存在於一系列的值中。

查詢樣例

樣例一

當分數表中存在與學生表中相同的學號,查詢其學號和姓名。

SELECT Sno, Sname
FROM Student S
WHERE EXISTS (SELECT * FROM Score WHERE Sno = S.Sno)

樣例二

查詢沒有成績同學的姓名和學號,使用 NOT EXISTS 子句實現。

SELECT SNO, SNAME
FROM Student S
WHERE NOT EXISTS (SELECT * FROM Score WHERE Sno = S.Sno)

集合運算

集合運算操作符

可以使用如下操作符,對 2 個 SELECT 結果集進行集合運算。

關鍵字 功能
UNION 對 2 個結果集做並集運算
INTERSECT 對 2 個結果集做交集運算
EXCEPT 對 2 個結果集做差集運算

查詢樣例

樣例一

假設此時有教師表 Teacher,表中具有以下字段和記錄。

將教師表和學生表匯總為一個表,使用 UNION 做並集運算。

SELECT Tname, Tsex FROM Teacher
UNION
SELECT Sname, Ssex FROM Student

樣例二

查詢學生表中小於 108 且大於 103 的所有學生信息,使用 INTERSECT 做交集運算。

SELECT * FROM Student WHERE Sno < '108'
INTERSECT
SELECT * FROM Student WHERE Sno > '103'

樣例三

查詢學生表中小於 108 但不大於 103 的所有學生信息,使用 EXCEPT 做差集運算。

SELECT * FROM Student WHERE Sno < '108'
EXCEPT
SELECT * FROM Student WHERE Sno > '103'

ALL、ANY 和 SOME

ALL、ANY 和 SOME 的功能

ALL 是所有,表示全部都滿足才返回 true。ANY(SOME)是任意一個,表示有任何一個滿足就返回 true。"=ANY"與"IN"相同,"<>ALL"與"NOT IN"相同。

查詢樣例

樣例一

查詢所以成績都及格的學生的信息(學號,姓名,課程號,課程名,成績,最低成績),可以先使用子查詢查出某位同學的所有成績,再結合 ALL 運算符作為過濾條件。

SELECT SC.Sno, S.Sname, C.Cname, SC.Degree, 
	(SELECT MIN(Degree) FROM Score SC2 WHERE SC.Sno = SC2.Sno) 最低分
FROM Score SC
JOIN Student S ON SC.Sno = S.Sno
JOIN Course C ON SC.Cno = C.Cno
WHERE 60 < ALL(
	SELECT Degree FROM Score010 SC3
	WHERE SC3.Sno = SC.Sno
)

樣例二

查詢成績有不及格的學生的信息(學號,姓名,課程號,課程名,成績, 最低成績)可以先使用子查詢查出某位同學的所有成績,再結合 ANY 運算符作為過濾條件。

SELECT SC.Sno, S.Sname, C.Cname, SC.Degree, 
	(SELECT MIN(Degree) FROM Score SC2 WHERE SC.Sno = SC2.Sno) 最低分
FROM Score SC
JOIN Student S ON SC.Sno = S.Sno
JOIN Course C ON SC.Cno = C.Cno
WHERE 60 > ANY(
	SELECT Degree FROM Score SC3
	WHERE SC3.Sno = SC.Sno
)

參考資料

《SqlServer 2014 數據庫技術實用教程》,胡伏湘、肖玉朝 主編,清華大學出版社


免責聲明!

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



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