期末複習題裡面碰到了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);
即,當exists子查詢結果非空,則當前column被選擇出來,否則不選中。not exists反之。if(condition != null)
then answer += column
else continue;
(1)從外層查詢中取出乙個元組,將元組相關的列值傳給內層查詢。
(2)執行內層查詢,得到子查詢操作的值。
(3)外查詢根據子查詢返回的結果或結果集得到滿足條件的行
(4)然後外層查詢取出下乙個元組重複做步驟1-3,直到外層的元組全部處理完畢。
以上面的查詢語句為例。我們知道,在select catid的過程中要遍歷所有catid,看哪個是符合條件的,才將其輸出,因此我們可以將這個過程看作乙個迴圈,每乙個迴圈catid分別等於c1. c2. c3. c4。由於在子查詢中,category**是在父查詢中引入的(這叫做相關子查詢),因此子查詢中的catid與父查詢中catid的值是一致的,即在第一次迴圈,子查詢變為:
同理,在這個查詢的子查詢中,student.stuid也隨上層的stuid變化,即最內層查詢在一開始實際上是: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
)
下面我們分析這個答案的執行過程。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(選修了全部課程)
即此處最內層查詢需要判斷該學生是否選修該門課程。考慮到not exists的邏輯,我們可以將內層迴圈這麼寫:select sname
from student
where not exists
( select cno
from course
where(學生沒有選修該門課程)
)
練習:至少選修了學生200215122選修的全部課程的學生號碼?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
));
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...