1. 程式人生 > 其它 >從0到1學資料庫:子查詢

從0到1學資料庫:子查詢

技術標籤:0-1資料庫

點選上方“羅曉勝”,馬上關注,您的支援對我幫助很大

上期文章

/ 前言 /

前面其實我們已經接觸過子查詢了,一句話解釋,子查詢就是將 上一次查詢的結果 作為 本次查詢的原始資料(或是查詢條件)。
適用範圍:當你的需求一次查詢無法滿足需求時(一次select找不到你要的資料,得多次查詢),子查詢所實現的功能,完全可以被多表聯查代替,子查詢能幹的事,多表聯查也能幹。

/ 正文 /

本章要點

• 子查詢語法介紹
• 單行子查詢
• 多行子查詢
• 相關子查詢
• EXISTS和NOT EXISTS操作符

子查詢的基本語法

• 子查詢的語法結構:SELECT 查詢列 FROM 表名 WHERE 列名 操作符 (SELECT 查詢列 FROM 表名);

• 括號內的查詢叫做子查詢(Subquery)或者內部查詢(Inner Query),外面的查詢叫做主查詢(Main query)或外部查詢 (Outer query)。

• 例 子查詢當做條件示例

查詢班級叫'一班'的所用使用者
SELECT id, name, age, c_class
FROM student
WHERE c_class = (SELECT id FROM t_class WHERE name = '一班');

子查詢注意事項

• 關於子查詢,需要注意以下幾點:– 子查詢需要寫在括號中;– 子查詢需要寫在運算子的右端;– 子查詢可以寫在WHEREHAVINGFROM子句中;– 子查詢中通常不寫ORDER BY子句。

子查詢的種類

單行子查詢(單列) 子查詢返回的記錄有且只有一條 多行子查詢(單列) 子查詢返回記錄的條數可以是一條或多條 多列子查詢 多列資料比較

單行子查詢

• 單行子查詢,子查詢返回的記錄有且只有一條。單行子查詢要 求使用單行操作符,即: – >大於 – >= 大於等於 – < 小於 – <= 小於等於 – =等於 – <> 不等於

WHERE子句中單行子查詢

• 例 查詢所有為一班的學生

SELECT id, name, age, c_class
FROM student
WHERE c_class = (SELECT id FROM student WHERE name = '一班');

HAVING子句中單行子查詢

• 除了在WHERE子句中外,也可以在HAVING子句中書寫子查詢。

• 例 查詢學生班級總數大於平均班級號的班級和班級數

SELECT c_class,COUNT(c_class)
FROM student
GROUP BY c_class
HAVING  COUNT(c_class) > (SELECT AVG(id) FROM t_class GROUP BY id);

多行子查詢

• 多行子查詢,子查詢返回記錄的條數可以是一條或多條。多行 子查詢需要使用多行操作符。常用的多行操作符包括:

– IN – ANY – ALL

IN、ANY、ALL的使用

• IN操作符和以前介紹的功能一致,判斷是否與子查詢的任意一 個返回值相同。返回的結果可以是一條或多條。

• 例 多行子查詢示例——IN操作符。

SELECT a.id,a.name, a.age ,a.c_class 
FROM student a 
WHERE a.c_class IN (SELECT b.id FROM t_class b where b.id = 1 or b.id =2);

• ANY:表示任意的。

– < ANY 比子查詢返回的任意一個結果小即可,即小於返回結 果的最大值。– = ANY 和子查詢中任意一個結果相等即可,相當於IN。– > ANY比子查詢返回的任意一個結果大即可,即大於返回結 果的最小值。

• ALL:表示所有的。

– < ALL 比子查詢返回的所有的結果都小,即小於返回結果的 最小值。– > ALL比子查詢返回的所有的結果都大,即大於返回結果的 最大值。– = ALL 無意義,邏輯上也不成立。

• 例 ANY操作符。

SELECT a.id,a.name, a.age,a.c_class 
FROM student a 
WHERE a.c_class > ANY (SELECT b.id FROM t_class b where b.id = 1 or b.id =2);

• 例 ALL操作符。

SELECT a.id,a.name, a.age ,a.c_class 
FROM student a 
WHERE a.c_class > ALL (SELECT b.id FROM t_class b where b.id = 1 or b.id =2);

多列子查詢

顯示名稱和班級與班級表同名的使用者

SELECT a.id,a.name, a.age ,a.c_class 
FROM student a 
WHERE (name, c_class) IN (SELECT name, id FROM t_class ) ;

子查詢中空值問題

• 例7-14 子查詢空值示例。

SELECT a.id,a.name, a.age ,a.c_class 
FROM student a 
WHERE a.c_class NOT IN (SELECT b.id FROM t_class b);

返回結果:未選定行

• 出現這種情況的原因有兩個:– 子查詢中返回值中包含有空值;– NOT IN操作符對空值不忽略。

• NOT IN操作符相當於<> ALL,即除了列表值的所有值,就包括了空值NULL,結果即為空。

FROM語句中子查詢

• 例 用子查詢當做連線查詢的另一張表

SELECT a.id,a.name, a.age ,a.c_class 
FROM student a , (SELECT id,name FROM t_class GROUP BY id) t
WHERE a.c_class = t.id ;

相關子查詢

  • 不相關子查詢:一條Sql語句中含有多條SELECT語句,先執行子查詢,再執行外查詢,子查詢可對立執行

    • 關鍵字:(1)先子查詢,再外查詢 2)可以對立執行,即可以單獨執行子查詢,對外查詢不干擾

  • 相關子查詢:子查詢不能獨立執行,並且先執行外查詢,再執行子查詢

    • 關鍵字:(1)先外查詢,再子查詢 2)子查詢不能獨立執行

當子查詢從一個在父查詢涉及的表中引用一個列時,執行相關子查詢。對於由父查詢處理的每一行相關子查詢都執行一次。相關子查詢被用於 row-by-row 處理。對父查詢的每一行,每個子查 詢被執行一次

• 相關子查詢中,內部查詢需引用外部查詢的列,進行互動判斷。相關子查詢的執行方式是一行行操作。外部查詢每執行一行操 作,內部查詢都要執行一次。

• 例 每個班級高於平均的使用者資訊, (也可通過分組判斷實現)。

SELECT a.id,a.name, a.age ,a.c_class ,a.c_score 
FROM student a 
WHERE a.c_score >(SELECT AVG(b.c_score) FROM student b WHERE b.c_class = a.c_class);

EXISTS和NOT EXISTS操作符

• 相關子查詢還可使用EXISTS和NOT EXISTS操作符。

• EXISTS判斷存在與否。具體操作如下:

– 子查詢中如果有記錄找到,子查詢語句不會繼續執行,返回 值為TRUE;
– 子查詢中如果到表的末尾也沒有記錄找到,返回值為FALSE。

• EXISTS子查詢並沒有確切記錄返回,只判斷是否有記錄。而且 只要找到相關記錄,子查詢就不需要再執行,然後再進行下面 的操作。這樣大大提高了語句的執行效率。

• NOT EXISTS正好相反,判斷子查詢是否沒有返回值。如果沒 有返回值,表示式為真,如果找到一條返回值,則為假。

• 例 查詢使用者表的班級ID 存在於班級表中的資料。

SELECT a.id,a.name, a.age ,a.c_class ,a.c_score 
FROM student a 
WHERE EXISTS (SELECT 1 FROM student b WHERE b.c_class = a.c_class);

• 因為EXISTS子句中,並沒有確切記錄返回,只返回真或假。所 以’1’只是佔位用,無實際意義。

• 例 查詢使用者表的班級ID 不存在於班級表中的資料。

SELECT a.id,a.name, a.age ,a.c_class ,a.c_score 
FROM student a 
WHERE NOT EXISTS (SELECT 1 FROM student b WHERE b.c_class = a.c_class);

• NOT EXISTS操作符因為運算方法與NOT IN不同,只會返回 TRUE或FALSE,不會返回空值,所以不需要考慮子查詢去除 空值的問題。

/ 總結 /

本文主要講了子查詢相關介紹,子查詢就像是父與子的巢狀關係,當一種查詢情況不滿足時,我們可以使用這種巢狀關係去處理。

往期推薦:

如何入門做軟體開發

為什麼我不推薦入行程式設計師

做全棧開發很難嗎

關注我的公眾號,學習技術或投稿

圖片

長按上圖,識別圖中二維碼即可關注