【SQL】通俗易懂透過GROUP BY,理解SQL子句優先級

寫在前面:大家好K。首先爲你點進這篇有趣的文章點贊👍!文章在撰寫過程中難免有疏漏和錯誤,歡迎你在下方留言指出文章的不足之處;如果覺得這篇文章對你有用,也歡迎你點贊和留下你的評論。更多內容請點進👉我的博客K。👈閱覽。

1. 引言

在學習GROUP BY子句時,可能難理解它到底在幹嘛,僅僅知道是對數據分組,想深入思考時又覺得迷迷糊糊,它如何影響查詢結果?它和SELECT的關係是什麼?這裏需要引入sql子句的優先級。每經過一級,會產生新的虛擬表,爲最終SELECT篩選提供數據

2. 英語複合句與SQL查詢語句

sql語法與英語複合句的語法及其相似,對句子結構的理解影響對整句句意的理解

(值得一提的是,我們稱group by"子句",英語的複合句裏有各種“從句”。但是在灣灣地區的英語文法裏,他們就把“從句”稱爲“子句”,像主詞子句、受詞子句等,這與sql“子句”的稱呼不謀而合)

3. 優先級

使用中不難發現,SQL查詢語句的優先級應該是這樣的:

FROM, WHERE > GROUP BY, HAVING > ORDER BY > SELECT

查詢時,每經過一級,原表受到各種限定後,新表總是越來越小,數據越來越接近我們想要的結果

3.1 第一級 FROM, WHERE

雖然FROM和WHERE是兩個獨立的關鍵字,但是他們應同屬於第一級

FROM是主語,WHERE是形容詞

FROM

爲整個查詢語句提供了原數據,數據量在這裏是最大的,還沒有經歷過修剪✂️

WHERE

爲原數據提供了簡單的處理,涉及到

  1. 比較:=, >, <, >=, <=, !=, <>, !>, !<, NOT+
  2. 範圍確定:BETWEEN AND, NOT BETWEEN AND
  3. 確定集合:IN, NOT IN
  4. 字符匹配:LIKE, NOT LIKE
  5. 空值:IS NULL, IS NNOT NULL
  6. 邏輯運算:AND, OR, NOT

經過WHERE處理後,數據量有所減少,以便進行下一步操作

3.2 第二級 GROUP BY, HAVING

GROUP BY與HAVING的關係,同FROM與WHERE的關係

FROM是主詞,WHERE是形容詞

GROUP BY使SQL可以批量處理上一步得到的數據,再經HAVING進行簡單處理

GROUP BY

GROUP BY xxx使在xxx屬性上,相同值的元組聚集在一起

FROM Students GROUP by Major

將各相同專業的學生分成一組(如:計科一組、生物一組、化學一組等)

方便之後對數據更準確的批量處理,如:獲取各專業的人數(COUNT(*))、獲取專業平均分(AVG(Grade))等

HAVING

HAVING同WHERE,處理分組後的數據,使數據再精確化,得到查詢結果最優解

3.3 第三級 ORDER BY

數據的篩選在第二階段完成時結束了,ORDER BY更多的是整理數據

當然整理結果也能作爲之後操作(如果後面還要手動處理 或 嵌套查詢還有外層等的話)的源

3.4 第四級 SELECT

終於到了末尾,SELECT接收到的源,是篩選整理後的最終表

這個表,已經比最開始FROM從庫中獲取的表要小很多,精簡很多了

SELECT會控制哪些數據被顯示出來,例如

// 顯示全部屬性
SELECT *

// 顯示學號、學生姓名
SELECT Sno, Sname

4. 總結

  1. 經過整理各子句優先級,發現GROUP BY的意義在於,使初步篩選的數據,再按指定屬性,相同的綁在一起,方便更準確的批量操作(通過HAVING)

  2. 以及讀寫SQL語句最好的順序是,以優先級從高到低進行讀寫爲主,再稍考慮細節

  3. 通過SELECT顯示的屬性,在有GROUP BY子句時,以執行GROUP BY子句後得到的表的屬性含義一致!!不是FROM那裏的!!!

❌而我之前搞不清GROUP BY的地方,可能是我潛意識把最熟悉的SELECT, FROM, WHERE先放在一起計算,再講結果帶到GROUP BY中分組,(逃

5. 示例

題目:查詢平均成績大於等於90分的學生學號和平均成績

/* 表結構爲
 * 學生課程成績表(學號, 姓名, 課程名, 成績)
 * 閱讀從1開始
 */
SELECT 學號, AVG(成績) // 4. 將學號、再次計算出的平均分顯示出來,且這裏的”學號“”成績“屬性是經過GROUP BY, HAVING子句得到的表裏的
FROM 學生課程成績表 // 1. 先看FROM,這裏獲取源表
GROUP BY 學號 // 2. 學號相同爲一組,含義:一個學生上的所有課程的成績跟隨學號放在一起
HAVING AVG(成績)> = 90; // 3. 僅留下平均成績大於90的學生的相關項

正確讀法已經標記在源碼上,❌我以前的想法可能是1423

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章