SQL關於相關子查詢與EXISTS的簡單總結

2021-06-27 21:36:14 字數 3647 閱讀 7879

期末複習題裡面碰到了sql查詢有關 相關子查詢 的內容,經過網上各種資料各種看,下面整理於此。

我們先看下面一道題。

建**如下:

查詢:給出被所有學生借閱過的圖書類別(類別,catname),注意類別為c1的顯示為「計算機」,其它類別顯示「其他」。

答案:

select case catid when 'c1' then '計算機' else '其它' end as 類別,catname from category where not exists(

select stuid from student where not exists(

select stuid from borrow,book

where borrow.bookid=book.bookid and book.catid=category.catid

and student.stuid=borrow.stuid

))

要理解這個查詢語句,我們考察以下幾個問題:

1. exists子查詢的邏輯:

select column

from table

where exists(condition);

等價於:

if(condition != null)

then answer += column

else continue;

即,當exists子查詢結果非空,則當前column被選擇出來,否則不選中。not exists反之。

(1)從外層查詢中取出乙個元組,將元組相關的列值傳給內層查詢。

(2)執行內層查詢,得到子查詢操作的值。

(3)外查詢根據子查詢返回的結果或結果集得到滿足條件的行

(4)然後外層查詢取出下乙個元組重複做步驟1-3,直到外層的元組全部處理完畢。

以上面的查詢語句為例。我們知道,在select catid的過程中要遍歷所有catid,看哪個是符合條件的,才將其輸出,因此我們可以將這個過程看作乙個迴圈,每乙個迴圈catid分別等於c1. c2. c3. c4。由於在子查詢中,category**是在父查詢中引入的(這叫做相關子查詢),因此子查詢中的catid與父查詢中catid的值是一致的,即在第一次迴圈,子查詢變為:

select stuid from student where not exists(

select stuid from borrow,book

where borrow.bookid=book.bookid and book.catid=『c1

and student.stuid=borrow.stuid

)

同理,在這個查詢的子查詢中,student.stuid也隨上層的stuid變化,即最內層查詢在一開始實際上是:

select stuid from borrow,book 

where borrow.bookid=book.bookid and book.catid=『c1

and1200910211=borrow.stuid

下面我們分析這個答案的執行過程。

首先最內層子查詢固定category.catid= 『c1』,然後連線四個**,分別判斷每個學生是否在**中。如果在**中,說明該學生借閱了c1類書籍,該子查詢非空,否則為空。

接下來看次內層子查詢,當最內層子查詢為空,該學生沒有借閱當前類別圖書,則次內層子查詢將當前學生學好號stuid加入答案集中,即沒有借閱當前類別圖書的學生集合。

最後是外層查詢,當次內層查詢為空,即不存在沒有借閱當前類別圖書的學生時,也就是當前圖書類別被所有學生借閱過,那麼這個類別就被加入結果集中。

好了上面這道題分析完成後我們換一道題試試正向的解決思路:

student:

sno

sname

s***

sage

sdept

200215121李勇

男cs200215122劉晨

女cs200215123王敏

女ma200215124張立

男cscourse

cno

cname

ccredit

1

資料庫2數學

3

資訊系統

4

作業系統

5

資料結構

6

資料處理

7

pascal語言 sc

sno

cno

credit

200215121

200215121

200215121

200215122

200215122

查詢選修了全部課程的學生姓名?

解決思路如下

select sname

from student

where(選修了全部課程)

即:

select sname

from student

where not exists

( select cno

from course

where(學生沒有選修該門課程)

)

即此處最內層查詢需要判斷該學生是否選修該門課程。考慮到not exists的邏輯,我們可以將內層迴圈這麼寫:

select sname

from student

where not exists

( select cno

from course

where not exists

( select cno

from sc

where sc.cno = course.cno and sc.sno = student.sno

));

練習:至少選修了學生200215122選修的全部課程的學生號碼?

mysql 非相關子查詢 相關子查詢一

1 子查詢在查詢語句中可出現的位置 2 子查詢的分類 3 子查詢的優化的思路 3.1 做子查詢優化的原因 3.2 子查詢優化技術 3.3 子查詢展開 4 最常見的子查詢型別的優化 4.1 in型別 4.2 all any some型別 4.3 exists型別 5 例項 二 相關子查詢和非相關子查詢...

mysql相關子查詢 SQL子查詢與連線查詢研究

假設有a b兩張表,其中b表有a表的外來鍵。在sql查詢中,我們經常有這樣的需求,需要根據b表中的條件篩選去查詢a表中的內容,以工作流查詢使用者的已辦流程為例來說明 1 歷史流程例項表act hi procinst 下述用a表代替 create table act hi procinst id va...

什麼是 相關子查詢 和 非相關子查詢

先執行主查詢,再針對主查詢返回的每一行資料執行子查詢,如果子查詢能夠返回行,則這條記錄就保留,否則就不保留。舉例1 相關子查詢查詢 查詢所有是領導的員工資訊 select from emp e1 where exists select from emp e2 where e1.empno e2.mg...