MySQL的巢狀查詢
定義我就不說了,子查詢就是內部的查詢,包含子查詢就是外部查詢!也就是說巢狀查詢一個是內部查詢一個是外部查詢,而且查詢是由內向外的。
提示一下:在group by和order by中的子查詢是沒有意義的!
子查詢的分類:
- 標量子查詢—返回單個值的查詢
- 列子查詢—返回單屬性一列的
- 行子查詢—返回多屬性一行的
- 表子查詢—多行多列
標量子查詢可以使用比較運算子(其他的查詢不可單獨使用比較運算子):
“=, >, <, >=, <=, <>(不等於)”
例子:
select * from student where number > ( select count(ID) from student);
上面的子查詢將算出學生的總人數,而外部查詢則是找出number大於學生總人數的學生資訊。重點是這裡的子查詢是一個標量子查詢,作為一個對比的例子:
select *
from student
where (number, SId) > (
select count(number), count(SId)
from student);
不是標量子查詢是不能直接使用比較運算子的,上面是一個錯誤的例子,即使是兩個和兩個相比較也是不對的。
以上是標量子查詢的特殊之處!!!
接下來講子查詢的共有的操作符:
“any(some), all, in(not in), exists(not exists)”
上面這些操作符,無論是哪種子查詢都是可以使用的(包括標量子查詢)
- any
任何一個,與一個比較運算子連用
select *
from student
where SId > any(
select SId
from student
where SId > 100);
外部查詢中的‘SId’大於任意一個子查詢中的‘SId’,那麼該查詢都會返回true。
和它相對的是all
- all
“所有”,要求大於子查詢結果中的所有值
select * from student where SId > all( select SId from student where SId > 100);
上面例子,只有外部查詢中的SId大於子查詢中的所有的SId才是返回true的元祖。
- in(not in)
檢查成員資格,可用於列舉集合
select *
from student
where (SId, number) in (
select SId, number
from student
where number > 100);
只有外部查詢中的(SId, number)存在於子查詢的結果中時才會返回true。這個外部查詢的屬性個數必須跟子查詢結果的屬性個數一致(可以是任意多個)
可用於列舉型別
select *
from student
where number in (100, 200, 300);
select *
from student
where (SId, number) in ((100, 151), (200, 161), (300, 171));
這就是所以說的in可以用在列舉型別中(其他的操作符都不可以)
- exists(not exists)
是一個邏輯運算子,返回true/false
select *
from student
where exists(
select *
from student
where number >100);
只要exists包含的子查詢中的結果大於等於一行,那麼exists就返回true!
子查詢差不多就這樣(但是以後要學會優化,畢竟子查詢有點慢不是嗎?)
我們再來講一下關於查詢的條件問題!
對於一個sql語句,它的篩選條件出現在語句的外部和內部查詢中都是有用的並且需要被計算的,考慮下面的sql語句:
select course_id
from section as S
where semester = 'Fall' and year = 2009 and
exists(select *
from section as T
where semester = 'Spring' and year = 2010 and S.course_id = T.course_id);
考慮這個語句,我們外部查詢篩選出‘Fall’和2009兩個關鍵字,然後exists僅僅是一個邏輯運算子,返回true/false。那麼篩選條件只有外部查詢中的兩個關鍵字嗎?當然不是,我們觀察到內部查詢中還有’S.course_id = T.course_id’,這個語句也會對外部查詢的一個篩選條件。
也就是說這個sql語句最終的關鍵字有"Fall", 2009, “Spring”, 2010.這個自己體會一下子就知道了。