今天來學習MySQL中的子查詢
。子查詢
就是指在一個查詢之中嵌套了其餘的若干查詢,即在一個select
查詢語句的where
和from
子句中包含另外一個select
查詢語句,外層select
查詢語句稱爲外層查詢
或父查詢
,where
子句中的select
語句稱爲內層查詢
或子查詢
。有時把上面這種狀況也稱爲嵌套查詢
。用戶可使用多個簡單的查詢構成複雜的查詢。本篇文章使用的數據和上一篇文章(MySQL學習筆記之對單表數據記錄的查詢操做)是同樣的。sql
最簡單的子查詢是返回一個值,一般和比較運算符連用。如查詢與「劉晨」在同一個系學習的學生:bash
# 查詢與劉晨在同一個系學習的學生
select s_id, s_name, s_dept
from tab_student
where s_dept = (
select s_dept
from tab_student
where s_name = '劉晨'
);
複製代碼
不相關子查詢
,若是子查詢的查詢條件依賴於父查詢,就被稱爲
相關子查詢
。
通常當子查詢返回的數據記錄爲多條時,通常會和IN、ANY、ALL和EXISTS
等關鍵字組合使用。函數
in
關鍵字主要用於查找屬性值是否屬於指定的集合,在《MySQL學習筆記之對單表數據記錄的查詢操做》文章中 已經學習了。由於子查詢的結果每每是一個集合,因此in
關鍵字是常常使用的。post
# 查詢選修了 2 號課程學生的姓名
select s_name
from tab_student
where s_id in (
select s_id
from tab_sc
where c_id = 2
);
複製代碼
關鍵字any
用來表示父查詢的條件爲知足子查詢返回結果中任意一條數據。能夠和比較運算符進行組合:學習
經過樣例進行理解:查詢非計算機系中比計算機系任意一個學生年齡小的學生姓名和年齡,也能夠理解成查詢非計算機系中年齡比計算機系中最大年齡小的學生的姓名和年齡。ui
# 查詢非計算機科學系中比計算機科學系任意一個學生年齡小的學生姓名和年齡
select s_name, s_age
from tab_student
where s_age < any (
select s_age
from tab_student
where s_dept = 'CS'
) and s_dept != 'CS';
複製代碼
關鍵字all
和關鍵字any
在用法上比較類似,表示主查詢的條件爲知足子查詢返回結果中全部數據記錄。一樣也能夠和比較運算符組合使用:spa
經過樣例進行理解:查詢非計算機科學系中比計算機科學系全部學生年齡都小的學生姓名和年齡,也能夠理解成非計算機系中學生的年齡比計算機系中最小年齡小的學生的姓名和年齡。code
# 查詢非計算機科學系中比計算機科學系全部學生年齡都小的學生姓名和年齡
select s_name, s_age
from tab_student
where s_age < all(
select s_age
from tab_student
where s_dept = 'CS'
) and s_dept != 'CS';
複製代碼
= | != | < | <= | > | >= | |
---|---|---|---|---|---|---|
any | in | -- | <max | <=max | >min | >=min |
all | -- | not in | <min | <=min | >max | >=max |
經過上表咱們知道同一個查詢請求能夠有多種方法,不一樣的方法其執行效率是不同的,咱們應根據本身的實際狀況進行選擇。用統計函數實現子查詢一般比直接用all
或any
查詢效率高。注: =all
通常爲永假,!=any
通常爲永真。cdn
關鍵字exists
用來判斷子查詢是否返回結果集,有結果集時爲true
不然爲fasle
。如:查詢全部選修了 3 號課程的學生姓名對象
# 查詢全部選修了 3 號課程的學生姓名
select s_name
from tab_student
where exists (
select *
from tab_sc
where s_id = tab_student.s_id and c_id = 3
);
複製代碼
tab_student.s_id
的值,與父查詢有關,也就是咱們上面剛說的
相關子查詢
。 與
exists
關鍵字對應的是
not exists
關鍵字,表示若是子查詢結果爲空,則外層的
where
子句返回真值,不然返回假值。
放在from
子句裏面的子查詢,會被看成一張臨時表成爲父查詢的查詢對象,必須爲臨時表指定一個別名。如:找出每一個學生超過他本身選修課程平均成績的課程號。
# 找出每一個學生超過他本身選修課程平均成績的課程號
select s_id, c_id
from tab_sc sc, (select s_id avg_id, avg(sc_grade) avg_grade
from tab_sc group by s_id
) as avg_sc
where sc.s_id = avg_sc.avg_id and sc.sc_grade >= avg_sc.avg_grade;
複製代碼
今天學習了MySQL中關於子查詢的一些基礎操做。介紹了簡單的子查詢,學習了in, any, all, exists
關鍵字的使用和臨時表基礎操做等。今天的學習告一段落,本文中有不對或不許確的地方,歡迎在評論區指定出來。