## 4.1 定義:
子查詢允許把一個查詢嵌套在另一個查詢當中。
子查詢,又叫內部查詢,相對于內部查詢,包含內部查詢的就稱為外部查詢。
子查詢可以包含普通select也可以包括的任何子句,比如:distinct、 group by、
order by、limit、join和union等;但是對應的外部查詢必須是以下語句之一:select、insert、update、delete、set或者do。
## 4.2 子查詢的位置:
select 中、標量子查詢
in,exists后,行、列子查詢
from ,join后跟表子查詢,且要給子表起別名(alias)
where 后,標量子查詢、行列子查詢,看where后面的具體條件
group by 和order by 中無實用意義。
<br>
## 4.3 子查詢分類
子查詢分為如下幾類:
1. 標量子查詢:返回單一值的標量,最簡單的形式。
2. 列子查詢:返回的結果集是 N 行一列。
3. 行子查詢:返回的結果集是一行 N 列。
4. 表子查詢:返回的結果集是 N 行 N 列。
- 標量子查詢:
是指子查詢返回的是單一值的標量,如一個數字或一個字符串,也是子查詢中最簡單的返回形式。可以使用 = > < >= <= <>
> 這些操作符對子查詢的標量結果進行比較,通常子查詢的位置在比較式的右側
- MySQL 列子查詢:
指子查詢返回的結果集是 N 行一列,該結果通常來自對表的某個字段查詢返回。
可以使用 = > < >= <= <> 這些操作符對子查詢的標量結果進行比較,通常子查詢的位置在比較式的右側
可以使用 IN、ANY、SOME 和 ALL 操作符,不能直接使用 = > < >= <= <> 這些比較標量結果的操作符。
```
* 示例:SELECT s1 FROM table1 WHERE s1 > ANY (SELECT s2 FROM table2)
```
```
好比“10 >any(11, 20, 2, 30)”,由于10>2,所以,該該判斷會返回TRUE;
只要10與集合中的任意一個進行比較,得到TRUE時,就會返回TRUE。
```
- MySQL 行子查詢:
指子查詢返回的結果集是一行 N 列,該子查詢的結果通常是對表的某行數據進行查詢而返回的集。 結果
```
* 例子:
SELECT * FROM article WHERE (title,content,uid) = (SELECT title,content,uid FROM blog WHERE bid=2)
```
- MySQL 表子查詢:
指子查詢返回的結果集是 N 行 N 列的一個表數據。
```
* 例子:
SELECT * FROM article WHERE (title,content,uid) IN (
SELECT title,content,uid FROM blog)
```
<br>
## 4.4 獨立子查詢
獨立子查詢是不依賴外部查詢而運行的子查詢。
什么叫依賴外部查詢?先看下面兩個sql語句。
**sql語句1:獲得所有hangzhou顧客的訂單號。**
```
select order_id from table2
where customer_id in(
select customer_id from table 1
where city='hangzhou')
```
**sql語句2:獲得城市為hangzhou,并且存在訂單的用戶。 **
```
select * from table1
where city='hangzhou' and exists(
select * from table2
where table1.customer_id=table2.customer_id)
```
對于sql語句1,我們將子查詢單獨復制出來,也是可以單獨執行的,就是子查詢與外部查詢沒有任何關系。
<br>
對于sql語句2,我們將子查詢單獨復制出來,就無法單獨執行了,由于sql語句2的子查詢依賴外部查詢的某些字段,
這就導致子查詢就依賴外部查詢,就產生了相關性。
<br/>
## 4.5 EXISTS謂詞
EXISTS是一個非常牛叉的謂詞,它允許數據庫高效地檢查指定查詢是否產生某些行。
根據子查詢是否返回行,該謂詞返回TRUE或FALSE。與其它謂詞和邏輯表達式不同的是,無論輸入子查詢是否返回行,EXISTS都不會返回UNKNOWN,對于EXISTS來說,UNKNOWN就是FALSE。
> 還是上面的語句,獲得城市為hangzhou,并且存在訂單的用戶。
```
select * from table1
where city='hangzhou' and exists(
select * from table2
where table1.customer_id=table2.customer_id)
```
>[info]關于IN和EXISTS的主要區別在于三值邏輯的判斷上。EXISTS總是返回TRUE或FALSE,
>[info]而對于IN,除了TRUE、FALSE值外,還有可能對NULL值返回UNKNOWN。但是在過濾器中,
>[info]UNKNOWN的處理方式與FALSE相同,因此使用IN與使用EXISTS一樣,SQL優化器會選擇相同的執行計劃。
>說到NOT IN和NOT EXISTS,對于輸入列表中包含NULL值時,NOT EXISTS和
NOT IN之間的差異就表現的非常大了。輸入列表包含NULL值時,IN總是返回TRUE和UNKNOWN,
因此NOT IN就會得到NOT TRUE和NOT UNKNOWN,即FALSE和UNKNOWN。