【SQL】子查詢詳解(附例題)

子查詢

子查詢的表示形式為:(SELECT 語句),它是INEXISTS等運算符的運算數,它也出現于FROM子句和VALUES子句。包含子查詢的查詢叫做嵌套查詢。嵌套查詢分為相關嵌套查詢不想關嵌套查詢

WHERE子句中的子查詢

比較運算符

子查詢的結果是元組的集合,即一個表,一般情況下,其關系模式有多列,關系實例有若干行。如果子查詢的結果是一個單列且單行的表,則可作為比較運算符的運算對象

例1 查詢與學號2000012的學生在同一個系的學生的詳細信息

:本文所有例題涉及的關系實例如下:
在這里插入圖片描述

學生信息都在Student表中;要查詢全部信息,使用*選擇所有列;查詢條件是和學號為‘2000012’的學生同一個系。
可以先查詢學號為‘2000012’的學生的系,再作為父查詢的條件查詢最終結果

SELECT *    --父查詢
FROM Student
WHERE Sdept = (SELECT Sdept   --子查詢FROM StudentWHERE Sno = '2000012');

查詢結果
在這里插入圖片描述
(實驗環境:SQL Sever 2012)

上面的SQL語句的WHERE子句中出現了子查詢,該語句的執行過程為:先執行子查詢,得到一個值’計算機’,再用這個值替換子查詢,得到一個新的SQL語句:

SELECT *    --父查詢
FROM Student
WHERE Sdept = '計算機';

然后執行新的SQL語句,得到結果。

該例的子查詢不依賴于父查詢而單獨執行,這樣的嵌套查詢叫做不相關嵌套查詢

:查詢選修了1156號課程并且成績大于該課程平均成績的學生的學號和成績

SELECT Sno, Grade
FROM SC
WHERE Cno = '1156' AND Grade > (SELECT AVG(Grade)FROM SCWHERE Cno = '1156');

在這里插入圖片描述
因為AVG是一個聚集函數,所以子查詢返回一個單行單列的數據,可以按上述方法使用

如果子查詢返回一個單列多行的表,則這個子查詢不能直接出現在比較表達式,需要使用SOMEALL修飾符,SOME是值集合的某一元素,ALL代表集合的全體元素

:查詢其他系比管理系某一學生年齡小的學生的姓名和年齡

查詢管理系學生的年齡:

SELECT Sage
FROM Student
WHERE Sdept = '管理';

該查詢結果為{18, 19, 19},不是一個單值。比某一學生年齡小要使用表達式Sage<SOME(18,19,19),如果Sage的值小于集合中某一元素的值,則比較結果為真,否則為假

SELECT Sname, Sage
FROM Student
WHERE Sdept <> '管理' AND Sage < SOME (SELECT SageFROM StudentWHERE Sdept = '管理');

在這里插入圖片描述

上面的查詢還可以使用聚集函數實現
比某一學生年齡就,就是要小于所有學生年齡的最大值

SELECT Sname, Sage
FROM Student
WHERE Sdept <>'管理' AND Sage < (SELECT MAX(Sage)FROM StudentWHERE Sdept = '管理');

:查詢其他系比管理系所有學生年齡都小的學生的姓名和年齡

SELECT Sname, Sage
FROM Student
WHERE Sdept <> '管理' AND Sage < ALL(SELECT SageFROM StudentWHERE Sdept = '管理');

該查詢同樣可以使用聚集函數
比所有學生年齡小,就是要小于所有學生年齡的最小值

SELECT Sname, Sage
FROM Student
WHERE Sdept <>'管理' AND Sage < (SELECT MIN(Sage)FROM StudentWHERE Sdept = '管理');

在這里插入圖片描述

不存在這樣的學生,所以查詢結果為空

SOME、ALL修飾符與聚集函數及謂詞IN的對應關系如表所示

=<><<=>>=
SOMEIN<MAX<=MAX>MIN>=MIN
ALLNOT IN<MIN<=MIN>MAX>=MAX

:查詢平均成績不小于85分的學生的姓名和所在系

按照題意,設計查詢過程:首先從Student表中任取一個學生,假設為x,然后從SC表中匯總出x的平均成績,如果平均成績不小于85,則輸出x的姓名和所在系

求學生x的平均成績的SQL語句為:

SELECT Sno, AVG(Grade)
FROM SC
WHERE Sno = x.Sno;

在SELECT語句中,除了表名、列名外,現在還出現了一個變量x,x叫做元組變量,表示某個表的一個元組。元組變量的名稱只能是表名或表的別名,這樣,通過元組變量的名稱就知道它代表哪個表的元組

最終查詢語句如下:

SELECT x.Sname, x.Sdept
FROM Student x
WHERE (SELECT AVG(Grade)FROM SCWHERE x.Sno = SC.Sno) > 85;

在這里插入圖片描述
這樣的嵌套查詢叫做相關嵌套查詢,因為子查詢有一個變量x,當未確定x的值時,無法得到查詢結果,而x代表父查詢的元組,與父查詢相關。不相關嵌套查詢的子查詢先于父查詢執行,并且只執行一次,而相關嵌套查詢對父查詢的每個元組都要執行一次子查詢

上述語句的執行過程如下:

  1. 執行父查詢,順序掃描Student表

  2. 取Student表的一個元組賦予元組變量x

  3. 執行父查詢的WHERE子句

    • 將第2步獲取的x傳送到子查詢
    • 執行子查詢,得到平均成績
    • 判斷平均成績是否大于等于85
  4. 如果WHERE子句的條件為真,則輸出x.Sname和x.Sdept

  5. 重復步驟2~4,繼續處理下一個元組,直到處理完Student表的所有元組

為了易于理解,可以使用表名作為元組變量名

謂詞IN

謂詞IN是二元運算符,一般書寫形式為A IN S,A是一個列名,S是一個集合。如果A是集合S的元素,則結果為真,否則結果為假

:查詢選修了1024號課程的學生的姓名和所在系

本例涉及Student表和SC表,分兩步構造。首先在SC表中查詢選修了1024號課程的學生集合,記為S

SELECT Sno
FROM SC
WHERE Cno = '1024';

然后對Student表的每個元組t,如果t.Sno∈S成立,則t是查詢結果之一。使用IN代替∈,使用元組變量表示t,就得到了下面的SQL語句

SELECT t.Sname, t.Sdept
FROM Student t
WHERE t.Sno IN(SELECT SnoFROM SCWHERE Cno = '1024');

在這里插入圖片描述
也可以直接用表名做為元組變量

SELECT Student.Sname, Student.Sdept
FROM Student
WHERE Student .Sno IN(SELECT SnoFROM SCWHERE Cno = '1024');

上述語句執行過程為:先執行子查詢,得到一個選了1024號課程的學生的集合,再執行外查詢,對Student表中的每個元組,測試元組在Sno列上的分量值是否在子查詢的結果中,如滿足則輸出這個元組

:查詢選修了“管理學”的學生學號和姓名

選修了管理學的學生:

SELECT Sno
FROM SC, Course
WHERE SC.Cno = Course.Cno AND Course.Cname = '管理學';

判斷Student表中的每個元組在Sno上的分量是否在學生集合中,得:

SELECT Sno, Sname
FROM Student
WHERE Student.Sno IN(SELECT SnoFROM SC, CourseWHERE SC.Cno = Course.Cno AND Course.Cname = '管理學');

SELECT Sno, Sname
FROM Student
WHERE Sno IN(SELECT SnoFROM SCWHERE Cno IN(SELECT CnoFROM CourseWHERE Cname = '管理學'));

在這里插入圖片描述

謂詞EXISTS

謂詞EXISTS是一元運算符,運算數是一個集合,如果該集合不是空集,則運算結果為真,否則運算結果為假。

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

SELECT Sname
FROM Student
WHERE Sno IN (SELECT SnoFROM SCWHERE Cno='1024');

這是一個不相關嵌套查詢,也可以使用EXISTS謂詞實現

對Student表的任何一個元組x,如果選修了1024號課程,則SC表中存在x的選課記錄,該記錄在Sno列上的分量等于x.Sno,在Cno上的分量等于’1024’。因此,集合SELECT * FROM SC WHERE Sno = x.Sno AND Cno = '1024'一定不是空集,則表達式EXISTS(SELECT * FROM SC WHERE Sno = x.Sno AND Cno = '1024)為真;如果x沒有選修1024號課程,則表達式結果為假

SELECT x.Sname
FROM Student x
WHERE EXISTS(SELECT *FROM SCWHERE Sno = x.Sno AND Cno = '1024');

在這里插入圖片描述
:查詢至少選修了學號為2000014的學生所選修的全部課程的學生的姓名及所在系

用R表示學號為2000014的學生所選修的全部課程的集合,S表示學生x選修的全部課程的集合,如果R?S成立,則x是要查找的學生

SELECT x.Sname x.Sdept
FROM Student x
WHERE x.Sno!='2000014' ANDNOT EXISTS (SELECT t.CnoFROM SC tWHERE Sno='2000014' AND NOT EXISTS(SELECT CnoFROM SCWHERE Sno = x.Sno AND Cno=t.Cno));

:查詢與學號為2000014的學生所選修的課程相同的學生的姓名

用R表示學號為2000014的學生選修的所有課程的集合,用S表示學生x選修的課程,如果R=S,則x是要查詢的學生

SELECT Student x
FROM Student x
WHERE x.Sno != '2000014' AND NOT EXISTS (SELECT Cno			--R∈SFROM SC yWHERE Sno = '2000014' AND NOT EXISTS(SELECT CnoFROM SCWHERE Sno = x.Sno AND Cno = y.Cno))ANDNOT EXISTS (SELECT CnoFROM SC zWHERE Sno = x.Sno AND NOT EXISTS(SELECT CnoFROM SCWHERE Sno = '2000014' AND Cno = z.Cno));

FROM 子句中的子查詢

FROM子句可以指定查詢要使用的表。子查詢的結果是一個表,但只是一個中間結果,并沒有存放在數據庫。為了在FROM子句使用子查詢,要給子查詢生成的臨時表命名,有時還要命名臨時表的列

:查詢每門課的名稱和平均成績

首先可以很容易的寫出查詢每門課的課程號和平均成績的SQL語句

SELECT Cno, AVG(Grade)
FROM SC
GROUP BY Cno;

在這里插入圖片描述
為了得到課程的名字,將臨時表和Course表連接即可

SELECT Cname, Grade
FROM Course, (SELECT Cno, AVG(Grade)FROM SCGROUP BY Cno) AS tmp(Cno, Grade)  --命名臨時表
WHERE Course.Cno = tmp.Cno;

也可以使用連接操作和分組操作實現

SELECT Cname, AVG(Grade)
FROM Course, SC
WHERE Course.Cno = SC.Cno
GROUP BY Cname;

外連接

使用條件連接運算時,只有滿足連接條件的元組才能作為查詢條件。假設A表和B表做條件連接,有時A表中會有某個元組t,由于在B表中沒有任何一個元組滿足與t的連接條件,因此t不會出現在連接結果中。

為了解決參與連接的表的某些元組沒有出現在連接結果中的問題,需要使用左外連接右外連接全外連接運算,作為區分,前面介紹的連接叫做內連接

左外連接

A表和B表做左外連接,其過程是先按照連接條件做連接運算,得到一個結果。如果A的某個元組t不在結果中,則將t和B的一個“萬能元組”做連接,這個萬能元組在所有列上取空值,即(NULL, NULL, …, NULL),形成一個新元組,加入最終結果。這個“萬能元組”并不真實存在

表達為

A LEFT OUTER JOIN B ON Condition

Course表和SC表做左外連接運算,物理課出現在查詢結果中

SELECT *
FROM Course LEFT OUTER JOIN SC ON Course.Cno = SC.Cno

在這里插入圖片描述

右外連接

A表和B表做右外連接,其過程是先按照連接條件做連接運算,得到一個結果。如果B的某個元組t不在結果中,則將t和A的一個“萬能元組”做連接,形成一個新元組,加入最終結果。

表達為

A RIGHTOUTER JOIN B ON Condition

全外連接

全外連接是左外連接右外連接

:查詢每門課的選修人數

根據題意,查詢結果需要包括每門課程,所以使用左外連接,然后對查詢結果分組、統計

有兩種寫法:

SELECT Cname, COUNT(*)
FROM Course LEFT OUTER JOIN SC ON Course.Cno = SC.Cno
GROUP BY Cname;

在這里插入圖片描述

SELECT Cname, COUNT(Sno)
FROM Course LEFT OUTER JOIN SC ON Course.Cno = SC.Cno
GROUP BY Cname;

在這里插入圖片描述

COUNT(*)函數用于統計分組中的元組數,不會省略值為NULL的元組,所以盡管無人選修物理課,任然會計數1,這是錯誤的;而COUNT(Sno)在計數時舍棄了NULL值,所以統計結果為0,是符合要求的

未完待續…

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/901022.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/901022.shtml
英文地址,請注明出處:http://en.pswp.cn/news/901022.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Stable Diffusion 擴展知識實操整合

本文的例子都是基于秋葉整合包打開的webui實現的 一、ADetailer——改善人臉扭曲、惡心 After detailer插件可以自動檢測生成圖片的人臉&#xff0c;針對人臉自動上蒙版&#xff0c;自動進行重繪&#xff0c;整個流程一氣呵成&#xff0c;因此可以避免許多重復的操作。除此之…

freertos內存管理簡要概述

概述 內存管理的重要性 在嵌入式系統中&#xff0c;內存資源通常是有限的。合理的內存管理可以確保系統高效、穩定地運行&#xff0c;避免因內存泄漏、碎片化等問題導致系統崩潰或性能下降。FreeRTOS 的內存管理機制有助于開發者靈活地分配和釋放內存&#xff0c;提高內存利用…

按規則批量修改文件擴展名、刪除擴展名或添加擴展名

文件的擴展名是多種多樣的&#xff0c;有些不同文件的擴展名之間相互是可以直接轉換的。我們工作當中最常見的就是 doc 與 docx、xls 與 xlsx、jpg 與 jpeg、html 與 htm 等等&#xff0c;這些格式在大部分場景下都是可以相互轉換 能直接兼容的。我們今天要介紹的就是如何按照一…

熱門面試題第15天|最大二叉樹 合并二叉樹 驗證二叉搜索樹 二叉搜索樹中的搜索

654.最大二叉樹 力扣題目地址(opens new window) 給定一個不含重復元素的整數數組。一個以此數組構建的最大二叉樹定義如下&#xff1a; 二叉樹的根是數組中的最大元素。左子樹是通過數組中最大值左邊部分構造出的最大二叉樹。右子樹是通過數組中最大值右邊部分構造出的最大…

MySQL學習筆記7【InnoDB】

Innodb 1. 架構 1.1 內存部分 buffer pool 緩沖池是主存中的第一個區域&#xff0c;里面可以緩存磁盤上經常操作的真實數據&#xff0c;在執行增刪查改操作時&#xff0c;先操作緩沖池中的數據&#xff0c;然后以一定頻率刷新到磁盤&#xff0c;這樣操作明顯提升了速度。 …

RNN、LSTM、GRU匯總

RNN、LSTM、GRU匯總 0、論文匯總1.RNN論文2、LSTM論文3、GRU4、其他匯總 1、發展史2、配置和架構1.配置2.架構 3、基本結構1.神經元2.RNN1. **RNN和前饋網絡區別&#xff1a;**2. 計算公式&#xff1a;3. **梯度消失:**4. **RNN類型**:&#xff08;查看發展史&#xff09;5. **…

django數據遷移操作受阻

錯誤信息&#xff1a; django.db.utils.OperationalError: (1227, Access denied; you need (at least one of) the SYSTEM_VARIABLES_ADMIN or SESSION_VARIABLES_ADMIN privilege(s) for this operation)根據錯誤信息分析&#xff0c;該問題是由于MySQL用戶 缺乏SYSTEM_VARI…

WinForm真入門(13)——ListBox控件詳解

WinForm ListBox 詳解與案例 一、核心概念 ?ListBox? 是 Windows 窗體中用于展示可滾動列表項的控件&#xff0c;支持單選或多選操作&#xff0c;適用于需要用戶從固定數據集中選擇一項或多項的場景?。 二、核心屬性 屬性說明?Items?管理列表項的集合&#xff0c;支持動…

局域網內文件共享的實用軟件推薦

軟件介紹 在日常辦公、學習或家庭網絡環境里&#xff0c;局域網內文件共享是個常見需求。有一款免費的局域網共享軟件非常適合這種場景。 這款局域網共享軟件使用起來非常簡單&#xff0c;不需要安裝&#xff0c;直接點擊就能使用。 它的操作流程簡單易懂&#xff0c;用戶只要…

ViewModel vs AndroidViewModel:核心區別與使用場景詳解

在 Android 的 MVVM 架構中&#xff0c;ViewModel 和 AndroidViewModel 都是用于管理 UI 相關數據的組件&#xff0c;但二者有一些關鍵區別&#xff1a; 1. ViewModel 基本用途&#xff1a;用于存儲和管理與 UI 相關的數據&#xff0c;生命周期與 Activity/Fragment 解耦&…

C語言--求n以內的素數(質數)

求n以內的素數&#xff0c;可以用試除法或者埃拉托斯特尼篩法&#xff08;埃氏篩法&#xff09; 文章目錄 試除法埃拉托斯特尼篩法&#xff08;埃氏篩法&#xff09;兩種方法測試運行效率 輸入&#xff1a;數字n 輸出&#xff1a;n以內所有的素數 不管是哪個方法&#xff0c;都…

Skynet.socket 函數族使用詳解

目錄 Skynet.socket 函數族使用詳解核心功能分類一、TCP 連接管理1. 監聽端口2. 建立連接3. 關閉連接 二、數據讀寫操作1. 阻塞式讀取2. 寫入數據2.1 socket.write(fd, data) 的返回值2.2 示例代碼2.3 關鍵注意事項2.4 與其他函數的區別2.5 底層原理2.6 總結 三、UDP 處理1. 創…

Unity Addressables資源生命周期自動化監控技術詳解

一、Addressables資源生命周期管理痛點 1. 常見資源泄漏場景 泄漏類型典型表現檢測難度隱式引用泄漏腳本持有AssetReference未釋放高異步操作未處理AsyncOperationHandle未釋放中循環依賴泄漏資源相互引用無法釋放極高事件訂閱泄漏未取消事件監聽導致對象保留高 2. 傳統管理…

aws(學習筆記第三十八課) codepipeline-build-deploy-github-manual

文章目錄 aws(學習筆記第三十八課) codepipeline-build-deploy-github-manual學習內容:1. 整體架構1.1 代碼鏈接1.2 全體處理架構2. 代碼分析2.1 創建`ImageRepo`,并設定給`FargateTaskDef`2.2 創建`CodeBuild project`2.3 對`CodeBuild project`賦予權限(`ECR`的`image rep…

在windows服務器使用Nginx反向代理云端的python實現的web應用

近日得閑&#xff0c;計劃將之前寫過的一些小桌面程序搬到云服務器上方便隨時隨地使用&#xff0c;同時也學習一些基本的網站開發和搭建知識&#xff0c;于是在AI的幫助下&#xff0c;基于niceguifastapi非常快捷地搞出來了一個前后端一體的網站程序&#xff0c;放在云服務器上…

全球貿易戰火重燃:50%關稅如何絞殺跨境電商低價模式?

一、政策高壓&#xff1a;美國對華貿易戰升級路線圖 2024年5月&#xff0c;美國國會《數字貿易壁壘法案》草案曝光&#xff0c;標志著中美貿易博弈進入新階段&#xff1a; ? 關稅武器精準打擊&#xff1a;成衣、消費電子、小家電稅率擬從10-25%躍升至50% ? 監管范圍擴大&…

0411 | 軟考高項筆記:項目立項

在軟考的項目管理知識體系中&#xff0c;技術可行性和經濟可行性是項目立項階段非常重要的兩個分析維度。以下是對這兩個考點的詳細解釋和記憶方法&#xff1a; 技術可行性分析 定義&#xff1a; 技術可行性分析是評估項目在現有技術條件和資源下是否能夠成功實施。它主要回答…

二分查找3:69. x 的平方根

鏈接&#xff1a;69. x 的平方根 - 力扣&#xff08;LeetCode&#xff09; 題解&#xff1a; 本題本質是二分查找右端點 x的算數平方根一定在1 ~ x 區間內&#xff0c;在1 ~ x區間內查找一個數num&#xff0c;num^2x&#xff0c;但實際上num不一定是整數&#xff0c;所以是n…

oracle大師認證證書有用嗎

專業能力的高度認可&#xff1a;OCM 是 Oracle認證的最高級別&#xff0c;是對數據庫從業人員技術、知識和操作技能的最高級認可&#xff0c;也是 IT 界頂級認證之一。它表明持證者具備處理關鍵業務數據庫系統和應用的能力&#xff0c;能夠解決最困難的技術難題和最復雜的系統故…

InnoDB 如何解決幻讀:深入解析與 Java 實踐

在數據庫事務管理中&#xff0c;幻讀&#xff08;Phantom Read&#xff09;是并發操作中常見的問題&#xff0c;可能導致數據一致性異常。MySQL 的 InnoDB 存儲引擎通過其事務隔離機制和多版本并發控制&#xff08;MVCC&#xff09;&#xff0c;有效解決了幻讀問題。作為 Java …