子查詢傳回結果形式不同:
标量子查詢(結果集隻有一行一列)
列子查詢(結果集隻有一列多行)
行子查詢(結果集有一行多列)
表子查詢(結果集一般為多行多列)
子查詢在主查詢中出現的位置不同:
select後面:
僅僅支援标量子查詢
from後面:
支援表子查詢
where或having後面:★
标量子查詢(單行) √
列子查詢 (多行) √
行子查詢
exists後面(相關子查詢)
表子查詢
子查詢和操作符:
單行操作符<,>,=,<=,>=,<>和标量子查詢一起使用;
any,all,in,not in和列子查詢一起使用,=any形式也可;
SELECT查詢養成去重的習慣SELECT distinct;
視圖和子查詢
視圖和子查詢是SQL查詢語句中功能性和靈活性更強的語句,可以了解成小子產品。那麼,學習這種具有獨立功能的子產品,應該做到以下幾點——
是什麼。如何使用。為什麼用。注意事項。舉例說明。
子查詢涉及到更多的條件,條件之間彼此牽連,
難在分析清楚條件中内含的嵌套邏輯。 這一部分進階促使我意識到複雜SQL查詢需要更多的實戰和練習,才能加深了解,提高熟練度,要結合更多的案例才有可能駕輕就熟。
主要包括視圖,子查詢,使用它們解決問題的思路,常用函數
一、視圖(視圖很像origin裡的模闆,科研狗的胡言亂語.....)
- 視圖不存放實際資料,存放的是sql語句,能夠建立一個新的臨時表;
- 建立視圖時,視圖列名的順序應該和查詢語句中的列的順序對應;
create view 視圖名稱(視圖列名1,視圖列名2,.....)
as
select 列名1,列名2,...
from 表名
......
練習
#建立視圖,按性别彙總人數
- 使用視圖時,查詢語句的字段名應該使用建立視圖時用的視圖列名。
select 視圖列名1,視圖列名2,....
from 視圖名稱;
(在from子句中,使用視圖名稱代替原表名稱。)
練習
#使用視圖,使用“按性别彙總”視圖彙總各性别的人數
注意事項:避免多個視圖嵌套,會影響SQL的性能;視圖中不能插入資料;
子查詢
- 在from子句中直接寫定義視圖的sql查詢語句,就形成了一個建立臨時表子查詢;
- 執行sql語句時,先運作内部sql子查詢語句,在運作外部sql查詢語句;
- 子查詢可以放在from子句中,也可以放在where子句中,視具體情況而定;
select 列名1,列名2,...
from (select 查詢語句)
as X;
練習
#使用子查詢按性别彙總人數
- 使用子查詢時常常和in,all,any結合使用,....in(子查詢);....all(子查詢);....any(子查詢);.....between(子查詢) and(子查詢);
練習1
#找出每個課程裡成績最低的學号,思路:1、按課程分組找到各自最低成績;2、查詢組内最低成績的學号,組内比較;(這是個關聯子查詢)
第一次查詢報錯,提示該子查詢中應該隻包含一列;粗心多寫了課程号,顯然in不能這麼用,其本質是等值判斷;
修改後,查詢正常運作,但是查詢結果不正确,課程&amp;amp;amp;amp;#39;0002&amp;amp;amp;amp;#39;出現60和80兩個成績,該查詢結果是“查詢哪些學生的成績與各課程最低成績裡任意一個相同”;
更正如下:
其中,&amp;amp;amp;amp;#39;in&amp;amp;amp;amp;#39;也可以替換為&amp;amp;amp;amp;#39;=&amp;amp;amp;amp;#39;來判斷;
練習2、3
#查詢哪些學生的成績比課程0002的全部成績裡的任意一個高,思路分兩步:
子查詢中的最低成績是60
#查詢哪些學生的成績比課程0002的全部成績都高,思路分兩步:
子查詢中最高成績為90
注意事項:- all,any(結果)中是集合,要避免算術運算誤用;
- 子查詢和視圖一樣避免嵌套,影響性能又難于了解;可以使用as為子查詢命名;
包含子查詢的SQL語句的運作順序:
标量子查詢——是指隻傳回一個值的子查詢,可作為單獨的一個結果使用。
- 它可能會用到分組函數,比如使用avg函數,但用了分組函數的子查詢未必就是标量子查詢,因為分組後可能有多個結果。
練習
#大于平均成績的學生的學号和成績
#成績位于差生<=60和優等生>80成績之間的學生的學号和成績
注意事項:- 标量子查詢僅僅傳回一個結果,是以不能錯誤的把分組函數和group by結合起來一起使用。
√select 學号,成績,(select avg(成績)from score);
×select 學号,成績,(select avg(成績)from score group by 課程号);
關聯子查詢——關聯子查詢有一點繞人,結合sql語句的執行順序和底層指令來了解
- 前面提到标量子查詢傳回單一值;若是需要多個組裡的内容自行比較,則需要分成多個組,而組内又需要單一值來實作算術比較時——這時即用到關聯子查詢。
練習
#查找每個課程中大于對應課程平均成績的學生
因為之前通讀過必知必會,此處乍一看關聯子查詢很像表的自連接配接,但是兩者并不相同,自連接配接是為了避免歧義導緻SQL解析出錯;關聯條件實際上是通過外内表的關聯對内表列值進行過濾。
個人了解為,SQL進行列值比對時并不是各行同時進行比對,舉個例子:(以下圖為例)
s1.課程号的第一行'0001'逐一與s2.課程号的每一行進行比對,并傳回相比對的行們,随後接着向下執行group by子句等;
s1.課程号的第二行'0002'逐一與s2.課程号的每一行進行比對,并傳回相比對的行們,随後接着向下執行group by子句等;
..........由此每次子查詢每次隻傳回單一值,與外部表相應列值進行比較。
- 該關聯條件每次篩選出和s1中某一行課程号同一組的課程号,是以子查詢隻傳回某一組相同課程号的一個平均成績。這個某一組就是由關聯條件限定出來的———這個where子句的機制,正是展現了1、SQL的語句執行順序;2、SQL中表之間過濾資料時怎麼工作的;
- 上面例子中的關聯子查詢group by去掉也不影響查詢結果,group by使語句更規範更易于了解。它是一個内外分開執行的過程,類似for語句的嵌套循環,豁然開朗。
視圖、子查詢關系圖
常用函數——(SQL中很多函數可以在需要時搜尋使用)
- 字元串函數;數值函數;日期函數;
- 彙總函數;
SQL ZOO練習
- 因為sql語句的豐富性,同樣的要求往往可以使用不同的思路解決。不同子句,異曲同工。