寫在前面:大家好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
爲原數據提供了簡單的處理,涉及到
- 比較:=, >, <, >=, <=, !=, <>, !>, !<, NOT+
- 範圍確定:BETWEEN AND, NOT BETWEEN AND
- 確定集合:IN, NOT IN
- 字符匹配:LIKE, NOT LIKE
- 空值:IS NULL, IS NNOT NULL
- 邏輯運算: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. 總結
-
經過整理各子句優先級,發現GROUP BY的意義在於,使初步篩選的數據,再按指定屬性,相同的綁在一起,方便更準確的批量操作(通過HAVING)
-
以及讀寫SQL語句最好的順序是,以優先級從高到低進行讀寫爲主,再稍考慮細節
-
通過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❌