子查詢 子查詢就是嵌套在查詢中的查詢, 目的是為了進行更複雜的查詢, 同時可以理解查詢的過程. 子查詢也分為兩種, 一種是關聯子查詢, 一種是非關聯子查詢. 關聯子查詢與非關聯子查詢 子查詢的劃分是依據了子查詢是否執行多次來進行劃分的. 子查詢從數據表中查詢數據結果, 如果這個數據結果只執行一次, ...
子查詢
子查詢就是嵌套在查詢中的查詢, 目的是為了進行更複雜的查詢, 同時可以理解查詢的過程.
子查詢也分為兩種, 一種是關聯子查詢, 一種是非關聯子查詢.
關聯子查詢與非關聯子查詢
子查詢的劃分是依據了子查詢是否執行多次來進行劃分的.
子查詢從數據表中查詢數據結果, 如果這個數據結果只執行一次, 之後這個數據結果作為主查詢的條件進行執行, 這種就是非關聯子查詢.
同樣, 如果子查詢需要執行多次, 即採用迴圈的方式, 先從外部查詢開始, 每次傳入子查詢進行查詢, 之後結果反饋給外部, 這種嵌套方式就是關聯子查詢.
舉個例子, 創建五張表, player表是球員表, team表是球隊表, team_score
是球隊比賽成績表, player_score
是球員比賽成績表, height_grades
是球員身高對應的等級表.
如果僅僅學習的話可以自己創建表, 看完之後自己出題自己來做, 沒必要非要上面的表, 如需下載請到 https://github.com/cystanford/sql_nba_data 去下載.
SELECT player_name, height FROM player WHERE height = (SELECT max(height) FROM player); // 查詢身高最高的球員信息
上面的子查詢就是非關聯子查詢, 查詢最高身高的子查詢僅僅執行了一次, 不依賴於外部查詢.
SELECT player_name, height, team_id FROM player AS a WHERE height > (SELECT avg(height) FROM player AS b WHERE a.team_id = b.team_id); // 查詢每個球隊中大於平均身高的球員信息
這個子查詢就是關聯子查詢了, 因為裡面的查詢球隊隊員平均身高依賴於外(主)查詢, 需要使用主查詢來獲取當前隊員是哪個球隊的.
EXISTS子查詢
關聯子查詢通常也和EXISTS一起使用, EXISTS子查詢用來判斷條件是否滿足, 滿足的話為TRUE, 不滿足的話為FALSE. 現在想查詢出場過的球員有哪些, 這個就需要到player_score中去查詢全部的球員Id, 有記錄表示出場過.
SELECT player_id, team_id, player_name FROM player WHERE EXISTS (SELECT player_id FROM player_score WHERE player.player_id = player_score.player_id); // EXISTS的關聯條件是寫在子查詢中的
有EXISTS, 自查就有NOT EXISTS, 也就是不存在, 與EXISTS是完全相反的結果.
與EXISTS有相同含義的還有IN, 這個下麵說.
集合比較子查詢
集合比較子查詢的作用是與另一個查詢結果集進行比較, 可以再子查詢中使用IN, ANY, ALL和SOME操作符.
現在想查詢出場過的球員有哪些, 可以這樣寫:
SELECT player_id, team_id, player_name FROM player WHERE player_id in (SELECT player_id FROM player_score WHERE player.player_id = player_score.player_id); // in查詢出場過的球員
哪種效率更好取決於查詢表於關聯表的數據大小, 查詢表達, IN的效率高, 相反, EXISTS的效率高.
接下來說說ANY和ALL, 這兩個通常需要使用比較符, 比較符包括了(>)(=)(<)(>=)(<=)(<>)等.
要查詢比印第安納步行者(對應的twam_id是1002)中任何一個球員身高高的球員信息, sql如下
SELECT player_id, player_name, height FROM player WHERE height > ANY (SELECT height FROM player WHERE team_id = 1002); // 主要身高高於子查詢中的人一個一個就可以
SQL: SELECT player_id, player_name, height FROM player WHERE height > ALL (SELECT height FROM player WHERE team_id = 1002); // 身高高於球員中的任意一個球員的身高, 簡單的說就是比球隊中身高最高的球員還要高.
SELECT p1.* FROM player p1 WHERE p1.height = (SELECT MAX(height) FROM player p2 WHERE p1.team_id = p2.team_id); // 查詢每支球隊中, 身高最高的球員信息
ANY和ALL關鍵字必須與一個比較操作符在一起使用, 不適用起不到集合比較的作用, ANY和ALL就沒有任何意義.
子查詢作為計算欄位
想查詢每支球員的球員數
SELECT team_name, (SELECT count(*) FROM player WHERE player.team_id = team.team_id) AS player_num FROM team;