天天看點

sql嵌套查詢傳回多個字段_list4 SQL複雜查詢

子查詢傳回結果形式不同:

标量子查詢(結果集隻有一行一列)

列子查詢(結果集隻有一列多行)

行子查詢(結果集有一行多列)

表子查詢(結果集一般為多行多列)

子查詢在主查詢中出現的位置不同:

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 表名
......
           

練習

#建立視圖,按性别彙總人數

sql嵌套查詢傳回多個字段_list4 SQL複雜查詢
  • 使用視圖時,查詢語句的字段名應該使用建立視圖時用的視圖列名。
select 視圖列名1,視圖列名2,....
from 視圖名稱;
(在from子句中,使用視圖名稱代替原表名稱。)
           

練習

#使用視圖,使用“按性别彙總”視圖彙總各性别的人數

sql嵌套查詢傳回多個字段_list4 SQL複雜查詢
注意事項:

避免多個視圖嵌套,會影響SQL的性能;視圖中不能插入資料;

子查詢

  • 在from子句中直接寫定義視圖的sql查詢語句,就形成了一個建立臨時表子查詢;
  • 執行sql語句時,先運作内部sql子查詢語句,在運作外部sql查詢語句;
  • 子查詢可以放在from子句中,也可以放在where子句中,視具體情況而定;
select 列名1,列名2,...
from (select 查詢語句)
as X;
           

練習

#使用子查詢按性别彙總人數

sql嵌套查詢傳回多個字段_list4 SQL複雜查詢
  • 使用子查詢時常常和in,all,any結合使用,....in(子查詢);....all(子查詢);....any(子查詢);.....between(子查詢) and(子查詢);

練習1

#找出每個課程裡成績最低的學号,思路:1、按課程分組找到各自最低成績;2、查詢組内最低成績的學号,組内比較;(這是個關聯子查詢)

sql嵌套查詢傳回多個字段_list4 SQL複雜查詢

第一次查詢報錯,提示該子查詢中應該隻包含一列;粗心多寫了課程号,顯然in不能這麼用,其本質是等值判斷;

sql嵌套查詢傳回多個字段_list4 SQL複雜查詢

修改後,查詢正常運作,但是查詢結果不正确,課程&amp;amp;amp;amp;amp;#39;0002&amp;amp;amp;amp;amp;#39;出現60和80兩個成績,該查詢結果是“查詢哪些學生的成績與各課程最低成績裡任意一個相同”;

更正如下:

sql嵌套查詢傳回多個字段_list4 SQL複雜查詢

其中,&amp;amp;amp;amp;amp;#39;in&amp;amp;amp;amp;amp;#39;也可以替換為&amp;amp;amp;amp;amp;#39;=&amp;amp;amp;amp;amp;#39;來判斷;

sql嵌套查詢傳回多個字段_list4 SQL複雜查詢

練習2、3

#查詢哪些學生的成績比課程0002的全部成績裡的任意一個高,思路分兩步:

sql嵌套查詢傳回多個字段_list4 SQL複雜查詢

子查詢中的最低成績是60

#查詢哪些學生的成績比課程0002的全部成績都高,思路分兩步:

sql嵌套查詢傳回多個字段_list4 SQL複雜查詢

子查詢中最高成績為90

注意事項:
  • all,any(結果)中是集合,要避免算術運算誤用;
  • 子查詢和視圖一樣避免嵌套,影響性能又難于了解;可以使用as為子查詢命名;
sql嵌套查詢傳回多個字段_list4 SQL複雜查詢

包含子查詢的SQL語句的運作順序:

sql嵌套查詢傳回多個字段_list4 SQL複雜查詢

标量子查詢——是指隻傳回一個值的子查詢,可作為單獨的一個結果使用。

  • 它可能會用到分組函數,比如使用avg函數,但用了分組函數的子查詢未必就是标量子查詢,因為分組後可能有多個結果。

練習

#大于平均成績的學生的學号和成績

sql嵌套查詢傳回多個字段_list4 SQL複雜查詢

#成績位于差生<=60和優等生>80成績之間的學生的學号和成績

sql嵌套查詢傳回多個字段_list4 SQL複雜查詢
注意事項:
  • 标量子查詢僅僅傳回一個結果,是以不能錯誤的把分組函數和group by結合起來一起使用。
√select 學号,成績,(select avg(成績)from score);
×select 學号,成績,(select avg(成績)from score group by 課程号);
           

關聯子查詢——關聯子查詢有一點繞人,結合sql語句的執行順序和底層指令來了解

  • 前面提到标量子查詢傳回單一值;若是需要多個組裡的内容自行比較,則需要分成多個組,而組内又需要單一值來實作算術比較時——這時即用到關聯子查詢。

練習

#查找每個課程中大于對應課程平均成績的學生

sql嵌套查詢傳回多個字段_list4 SQL複雜查詢

因為之前通讀過必知必會,此處乍一看關聯子查詢很像表的自連接配接,但是兩者并不相同,自連接配接是為了避免歧義導緻SQL解析出錯;關聯條件實際上是通過外内表的關聯對内表列值進行過濾。

個人了解為,SQL進行列值比對時并不是各行同時進行比對,舉個例子:(以下圖為例)

sql嵌套查詢傳回多個字段_list4 SQL複雜查詢

s1.課程号的第一行'0001'逐一與s2.課程号的每一行進行比對,并傳回相比對的行們,随後接着向下執行group by子句等;

s1.課程号的第二行'0002'逐一與s2.課程号的每一行進行比對,并傳回相比對的行們,随後接着向下執行group by子句等;

..........由此每次子查詢每次隻傳回單一值,與外部表相應列值進行比較。

  • 該關聯條件每次篩選出和s1中某一行課程号同一組的課程号,是以子查詢隻傳回某一組相同課程号的一個平均成績。這個某一組就是由關聯條件限定出來的———這個where子句的機制,正是展現了1、SQL的語句執行順序;2、SQL中表之間過濾資料時怎麼工作的;
  • 上面例子中的關聯子查詢group by去掉也不影響查詢結果,group by使語句更規範更易于了解。它是一個内外分開執行的過程,類似for語句的嵌套循環,豁然開朗。

視圖、子查詢關系圖

sql嵌套查詢傳回多個字段_list4 SQL複雜查詢

常用函數——(SQL中很多函數可以在需要時搜尋使用)

  1. 字元串函數;數值函數;日期函數;
  2. 彙總函數;

SQL ZOO練習

  • 因為sql語句的豐富性,同樣的要求往往可以使用不同的思路解決。不同子句,異曲同工。
sql嵌套查詢傳回多個字段_list4 SQL複雜查詢
sql嵌套查詢傳回多個字段_list4 SQL複雜查詢
sql嵌套查詢傳回多個字段_list4 SQL複雜查詢
sql嵌套查詢傳回多個字段_list4 SQL複雜查詢
sql嵌套查詢傳回多個字段_list4 SQL複雜查詢
sql嵌套查詢傳回多個字段_list4 SQL複雜查詢
sql嵌套查詢傳回多個字段_list4 SQL複雜查詢
sql嵌套查詢傳回多個字段_list4 SQL複雜查詢
sql嵌套查詢傳回多個字段_list4 SQL複雜查詢
sql嵌套查詢傳回多個字段_list4 SQL複雜查詢