從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 = '一班');
子查詢注意事項
• 關於子查詢,需要注意以下幾點:– 子查詢需要寫在括號中;– 子查詢需要寫在運算子的右端;– 子查詢可以寫在WHERE,HAVING,FROM子句中;– 子查詢中通常不寫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,不會返回空值,所以不需要考慮子查詢去除 空值的問題。
/ 總結 /
本文主要講了子查詢相關介紹,子查詢就像是父與子的巢狀關係,當一種查詢情況不滿足時,我們可以使用這種巢狀關係去處理。
往期推薦:
關注我的公眾號,學習技術或投稿
長按上圖,識別圖中二維碼即可關注