上節課我們通過子查詢,完成了查詢的最高分學生的需求,今天我們來學習子查詢的分類,以及通過子查詢來完成工作中經常遇到一些個性化需求。
子查詢概念:
一個SELECT語句嵌套在另一個SELECT語句中,子查詢也叫做內部查詢,而包含子查詢的語句又稱為外部查詢或主查詢,子查詢自身可以包含一個或多個子查詢,一個查詢語句中可以嵌套任意數量的子查詢
子查詢可分類:
非相關子查詢:獨立於外部查詢,子查詢只執行一次,執行完將結果傳遞給外部查詢相關子查詢:依賴於外部查詢的數據,外部查詢每執行一次,子查詢就執行一次
面試題:
還是這道數據庫面試題檸檬班第30期學生要畢業了,他們的成績存放在下表中,寫出以下的SQL語句
題目一:查詢最新的一條記錄
Order by 方式:
降序排列然后得到我們最新的一條記錄,這是我們常寫的一種方式
SELECT * FROM tb_lemon_grade ORDER BY id DESC LIMIT 1;
子查詢方式:
但查詢最新一條記錄,也可以這么去思考:查看id值最大(id是自動增長的,最新表示id值最大)的記錄,所以可以這么去寫查詢
SELECT * FROM tb_lemon_grade WHERE id = ( SELECT max(id) FROM tb_lemon_grade);
其中子查詢SELECT max(id) FROM tb_lemon_grade查詢的是記錄表中最大的一個id,在整個查詢中,只會查詢一遍,這種就是非相關子查詢,執行完畢后,會將值傳遞給外部查詢。
題目二:查詢Linux成績高於平均分的所有同學
子查詢方式:
SELECT * FROM tb_lemon_grade WHERE Linux > ( SELECT avg(Linux) FROM tb_lemon_grade );
上面子查詢SELECT avg(Linux) FROM tb_lemon_grade也是非相關子查詢,語句只會執行一遍
關聯查詢方式:
這個題目我們可以使用兩個表的關聯查詢得到結果
SELECT t1.* FROM tb_lemon_grade t1,(SELECT avg(Linux) avgLinux FROM tb_lemon_grade) t2 where t1.Linux>t2.avgLinux;
題目三:查詢每個班級Linux成績高於本班Linux平均分的所有同學:
子查詢方式
SELECT * FROM tb_lemon_grade t1 WHERE t1.Linux >( SELECT avg(t2.Linux) FROM tb_lemon_grade t2 WHERE t1.class_name = t2.class_name );
我們來分析下這個題目,查詢每個班級Linux成績高於本班Linux平均分的所有同學,而每個班的Linux平均分不同,所以我們采用相關子查詢,語句中的這個子查詢依賴於外部的查詢( 子查詢中的t1.class_name = t2.class_name就是外部的表),外部查詢每執行一次,子查詢就執行一次。
分組的方式寫子查詢:
SELECT * FROM tb_lemon_grade t1 WHERE t1.Linux > ( SELECT avg(t2.Linux) FROM tb_lemon_grade t2 GROUP BY t2.class_name HAVING t1.class_name = t2.class_name );
關聯查詢方式:
通過分組查詢出每個班的最高分,再與原表進行等值連接查詢,得到最后結果。
SELECT * FROM tb_lemon_grade t1, ( SELECT avg(Linux) avgLinux, class_name FROM tb_lemon_grade GROUP BY class_name ) t2 WHERE t1.class_name = t2.class_name AND t1.Linux>t2.avgLinux;