MySQL學(xué)習(xí)之分組查詢的用法詳解
該章節(jié)來開始學(xué)習(xí)分組查詢,上一章節(jié)我們學(xué)習(xí)了聚合函數(shù),默認(rèn)統(tǒng)計(jì)的是全表范圍內(nèi)的數(shù)據(jù),配合上 WHERE 就能夠縮小統(tǒng)計(jì)的范圍了。但是這并不能滿足我們的要求,比如說我們按照之前的數(shù)據(jù)表查詢每個(gè)部門的平均底薪是多少?這樣的記錄就需要針對(duì)部門編號(hào)進(jìn)行分組了。根據(jù)分組的情況統(tǒng)計(jì)分組內(nèi)的最大值、最小值、平均值等等。如此就能夠滿足剛剛提到的 “查詢每個(gè)部門的平均底薪” 這樣的需求了,另外,“分組查詢” 是 SQL 中很重要的一個(gè)語法,大家一定要好好掌握它。
為什么要分組
上面也提到,聚合函數(shù)默認(rèn)是對(duì)全表范圍內(nèi)的數(shù)據(jù)做統(tǒng)計(jì),在一些特定的場(chǎng)景下不太適用,就比如 對(duì)數(shù)據(jù)分別進(jìn)行統(tǒng)計(jì)的 場(chǎng)景。
由于聚合函數(shù)的這樣的局限性,也就產(chǎn)生了分組的概念,于是就有了分組的語法。
分組的語法是通過 “GROUP BY” 來實(shí)現(xiàn)的。
"GROUP BY" 子句的作用是通過一定的規(guī)則將一個(gè)數(shù)據(jù)集劃分成若干個(gè)小的區(qū)域,然后再針對(duì)每個(gè)小區(qū)域分別進(jìn)行數(shù)據(jù)匯總處理
分組語句演示案例:(計(jì)算每一個(gè)部門的平均底薪)
SELECT deptno, AVG(sal) FROM t_emp GROUP BY deptno; -- 利用 GROUP BY 子句將 deptno 進(jìn)行分組,在利用 AVG() 聚合函數(shù)計(jì)算各個(gè) deptno(部門) 的平均月薪
這里的小數(shù),可能看著不太舒服,我們可以使用 ROUND() 函數(shù)將 平均工資四舍五入變成整數(shù)。
SELECT deptno, ROUND(AVG(sal)) FROM t_emp GROUP BY deptno;
逐級(jí)分組
有的時(shí)候僅有大的分組還不夠,還需要在大的分組里面劃分出曉得分組,然后再執(zhí)行統(tǒng)計(jì)計(jì)算,于是就有了逐級(jí)分組。
什么是逐級(jí)分組? MySQL 數(shù)據(jù)庫支持多列分組條件,執(zhí)行的時(shí)候按照多列去依次執(zhí)行,這就是逐級(jí)分組。
示例如下:(查詢每個(gè)部門里,每種職位的人員數(shù)量和平均工資。)
SELECT deptno, job, COUNT(*), AVG(sal) FROM t_emp GROUP BY deptno, job ORDER BY deptno; -- 首先要按照部門對(duì)員工進(jìn)行分組,在部門里,還要按照職務(wù)去分組; 就是 "GROUP BY deptno, job" -- 然后再用 聚合函數(shù)的 AVG 計(jì)算平均的月薪; 就是 "SELECT deptno, job, COUNT(*), AVG(sal)" -- 最后按照 deptno(部門編號(hào)) 排序,使用 ORDER BY 進(jìn)行升序排序。
逐級(jí)分組對(duì) SELECT 子句的要求
查詢語句中如果包含有 “GROUP BY” 子句,那么 “SELECT” 子句中的內(nèi)容就必須要遵守以下規(guī)定
"SELECT" 子句中可以包含聚合函數(shù),或者 "GROUP BY" 子句的分組列,其余內(nèi)容均不可以出現(xiàn)在 "SELECT" 子句中
SQL 示例如下:(遵守規(guī)定示例)
SELECT deptno, COUNT(*), AVG(sal) FROM t_emp GROUP BY deptno;
SQL 示例如下:(不遵守規(guī)定示例)
SELECT deptno, COUNT(*), AVG(sal), sal FROM t_emp GROUP BY deptno; -- 這條語句是無法執(zhí)行成功的,因?yàn)樵?"SELECT" 子句中,有一個(gè) "sal" 的字段 -- 這個(gè) "sal" 字段 沒有在 GROUP BY 中去分組,本身也沒有聚合函數(shù),就是一個(gè)普通的字段 -- 造成無法執(zhí)行、報(bào)錯(cuò)的原因是因?yàn)椋?SELECT deptno, COUNT(*), AVG(sal), sal" -- 中的 "deptno、COUNT(*)、AVG(sal)" 返回的是 "GROUP BY" 一個(gè)結(jié)果集分組的同級(jí)信息; -- 而 "sal" 字段又是多條匹配記錄,前后肯定是匹配不上的,所以這個(gè) SQL 語句是無法執(zhí)行成功的。 -- 同時(shí)因?yàn)闃?biāo)準(zhǔn)的 SQL 規(guī)定,對(duì)表進(jìn)行聚合查詢的時(shí)候,只能在 SELECT 子句中寫下面 3 種內(nèi)容: -- 通過 GROUP BY 子句指定的聚合鍵、聚合函數(shù)(SUM 、AVG 等)、常量。 -- 所以在使用 SQL 語句記性數(shù)據(jù)表查詢時(shí),一定要嚴(yán)格遵守 SQL 的語法規(guī)定。
對(duì)分組結(jié)果集再次做匯總計(jì)算
來看一個(gè)示例:(查詢 員工表中各個(gè)部門的人數(shù),各個(gè)部門的平均月薪、最大月薪、最小月薪、按照員工號(hào)進(jìn)行排序,并針對(duì)各個(gè)部門再次做一個(gè)匯總統(tǒng)計(jì)。)
SELECT deptno, COUNT(*), AVG(sal), MAX(sal), MIN(sal) FROM t_emp GROUP BY deptno WITH ROLLUP; -- 這里的 "WITH ROLLUP" 子句就是針對(duì) "deptno"分組的結(jié)果集,再一次的進(jìn)行匯總計(jì)算
PS:該 SQL 語句主要是為了體現(xiàn) "WITH ROLLUP" 關(guān)鍵字的效果,是對(duì)聚合函數(shù)的再次執(zhí)行匯總計(jì)算。
GROUP_CONCAT 函數(shù)
上文中的 "逐級(jí)分組對(duì) SELECT 子句的要求" 部分的時(shí)候解釋了為什么會(huì)有這樣的要求,就是聚合函數(shù)返回一條記錄的結(jié)果與非分組字段的多條記錄的結(jié)果無法匹配。
如果想要想要匹配,那就要把非分組的字段的多條記錄轉(zhuǎn)換成一條記錄,MySQL 提供的 GROUP_CONCAT 函數(shù)就可以將分組查詢中的非分組字段中的多條記錄合并成一條記錄。
SQL 語句 "GROUP_CONCAT" 示例如下:(查詢每個(gè)部門內(nèi)底薪超過 2000元的人數(shù)和員工姓名,這里的員工姓名就是非分組的字段)
SELECT deptno, GROUP_CONCAT(ename), AVG(sal),COUNT(*) FROM t_emp WHERE sal >= 2000 GROUP BY deptno; -- 查詢員工表,篩選條件為月薪大于等于 2000 ,以 "deptno" 為分組 -- "ename" 字段沒有分組,但是我們使用 "GROUP_CONCAT" 函數(shù)將 "ename" 的多條返回記錄轉(zhuǎn)換為一條記錄
GROUP BY 子句的執(zhí)行順序
截止到目前為止,我們所學(xué)習(xí)的所有子句,執(zhí)行順序如下:
FROM ---> WHERE ---> GROUP BY ---> SELECT ---> ORDER BY ---> LIMIT
到此這篇關(guān)于MySQL學(xué)習(xí)之分組查詢的用法詳解的文章就介紹到這了,更多相關(guān)MySQL分組查詢內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SSM實(shí)現(xiàn)mysql數(shù)據(jù)庫賬號(hào)密碼密文登錄功能
這篇文章主要介紹了SSM實(shí)現(xiàn)mysql數(shù)據(jù)庫賬號(hào)密碼密文登錄功能,本文分為三步給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2019-08-08SQL如何使用正則表達(dá)式對(duì)數(shù)據(jù)進(jìn)行過濾
正則表達(dá)式的作用是匹配文本,將一個(gè)正則表達(dá)式與一個(gè)文本串進(jìn)行比較,下面這篇文章主要給大家介紹了關(guān)于SQL如何使用正則表達(dá)式對(duì)數(shù)據(jù)進(jìn)行過濾的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-09-09關(guān)于com.mysql.jdbc.Driver與com.mysql.cj.jdbc.Driver的區(qū)別
這篇文章主要介紹了關(guān)于com.mysql.jdbc.Driver與com.mysql.cj.jdbc.Driver的區(qū)別及說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08Mysql 5.7.19 免安裝版配置方法教程詳解(64位)
這篇文章主要介紹了Mysql 5.7.19 免安裝版配置方法教程詳解,需要的朋友可以參考下2017-08-08阿里云服務(wù)器手動(dòng)實(shí)現(xiàn)mysql雙機(jī)熱備的兩種方式
阿里云服務(wù)器由于不支持keepalive虛擬ip,導(dǎo)致無法通過keepalive來實(shí)現(xiàn)mysql的雙機(jī)熱備。我們這里要實(shí)現(xiàn)阿里云的雙機(jī)熱備有兩種方式。感興趣的朋友跟隨小編一起看看吧2019-10-10防止MySQL重復(fù)插入數(shù)據(jù)的三種方法
在MySQL進(jìn)行數(shù)據(jù)插入操作時(shí),總是會(huì)考慮是否會(huì)插入重復(fù)數(shù)據(jù),之前的操作都是先根據(jù)主鍵或者唯一約束條件進(jìn)行查詢,有就進(jìn)行更新沒有就進(jìn)行插入。代碼反復(fù)效率低下。2020-09-09Mysql快速插入千萬條數(shù)據(jù)的實(shí)戰(zhàn)教程
這篇文章主要給大家介紹了關(guān)于Mysql快速插入千萬條數(shù)據(jù)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03MySQL數(shù)據(jù)庫基礎(chǔ)學(xué)習(xí)之JSON函數(shù)各類操作詳解
很多日常業(yè)務(wù)場(chǎng)景都會(huì)用到j(luò)son文件作為數(shù)據(jù)存儲(chǔ)起來,而mysql5.7以上就提供了存儲(chǔ)json的支撐。這篇文章就為大家整理了MySQL中JSON函數(shù)的各類操作,感興趣的可以了解一下2023-02-02mysql中mysql-bin.000001是什么文件可以刪除嗎
這篇文章主要介紹了mysql中mysql-bin.000001是什么文件可以刪除嗎,需要的朋友可以參考下2019-05-05