分組查詢(group by)
# -------------------------9、分組查詢 ------------------------- # 取得每個工作崗位的工資合計,要求顯示崗位名稱和工資合計。 select * from emp; select job, sum(sal) from emp group by job; # 按照工作崗位和部門編碼分組,取得的工資合計 # 在 SQL 語句中若有 group by 語句,那么在 select 語句后面只能跟分組函數+參與分組的字段。 select deptno, job, sum(sal) from emp group by deptno, job; # 取得每個崗位的平均工資大於 2000 # 有group by語句,后面不能有where select job, avg(sal) from emp group by job having avg(sal)>2000;
知識擴展:
分組查詢group by的用法及講解
參考資料:https://baijiahao.baidu.com/s?id=1664040284917893293&wfr=spider&for=pc
group by是sql中比較強大的功能,是在對數據分組統計時必不可少的用法。但是,對於很多經驗不足的同學,經常會寫錯。今天我們就以Oracle為例,來講解下分組查詢group by的用法。
一,group by 語法規范
首先我們准備一張Student表
CREATE TABLE STUDENT
( SNO VARCHAR2(10) not null,
SNAME VARCHAR2(20),
SAGE NUMBER(2),
SSEX VARCHAR2(5) )
往里面插入幾條學生實體記錄。再查看數據:
SELECT * FROM STUDENT;

我們使用group by將這些數據按照性別進行分組:
SELECT * FROM STUDENT GROUP BY SSEX;
不幸的是,執行失敗了,提示:不是 GROUP BY 表達式!(我用navicat 連接mysql 執行 SELECT * FROM t_student GROUP BY sex; 成功啊!不過還是按照他的思路搬運過來先,或許Oracle不行呢。)

原因是group by 分組查詢,select子句后的字段必須來自group by后的分組字段。於是 我們執行SQL
SELECT SSEX FROM STUDENT GROUP BY SSEX;

這下成功地將數據分為了兩組。我們接下來使用下聚合函數
SELECT SSEX,MAX(SAGE) FROM STUDENT GROUP BY SSEX;
注意這條sql語句,select子句中聚合函數使用了SAGE(年齡)這個字段,那會不會違背了前面所說的 “select子句后的字段必須來自group by后的分組字段”這個規律呢,我們來執行一下:

能正常執行,成功地按照了性別分組,並且查詢出了性別對應年齡最大的學生。於是我們可以得出規律:select子句后的任一非聚合函數字段都應來源於group by 分組語句后,否則語法會編譯不通過。
二,group by 用法的意義
我們都知道group by 是用來分組的,那么具體怎么分組,對應的語句又怎么寫呢?我們一起來研究下。
示例:按照年齡將學生分組。
很多人會這樣寫:
SELECT * FROM STUDENT GROUP BY SSAGE
上面已經證實過了,這樣子語法不通過。
SELECT SSAGE FROM STUDENT GROUP BY SSAGE
如果這樣寫的話,也只會單純地將年齡分組。

正確的寫法是這樣的:
SELECT SNAME,SAGE FROM STUDENT GROUP BY SAGE,SNAME ORDER BY SAGE;

可以看出,group by 分組是按照group by后的字段組合來進行分組的。也就是說你group by后給了我幾個字段,我就按照這幾個字段組合成一條記錄,若有重復的記錄,就屬於同一組,最后將所有的分組返回給你。
同時上訴sql的order by語句也要符合group by的語法,即order by后的字段必須來源於group by分組字段。所以我們可以把分出來的組理解為試圖,所有的其他操作都基於這張視圖。
三,分組查詢的篩選where和having
示例:查詢出性別為男的學生並按照年齡分組,並篩選出年齡大於21歲的
我們首先實現錢半部分:查詢出性別為男的學生並按照年齡分組
SELECT SNAME,SAGE FROM STUDENT where SSEX='男' GROUP BY SNAME,SAGE

然后使用having語句篩選:
SELECT SNAME,SAGE FROM STUDENT where SSEX='男' GROUP BY SNAME,SAGE HAVING SAGE>'21'
查詢結果:

可以看到,小於等於21歲的男同學都被過濾掉了。
我們這里可以進行總結下:
1. 當在一個SQL中同時使用where和group by和having子句時,其執行順序為:where>group by>having。
2. 同時where子句作用於表或者視圖,having子句作用於組,having子句必須作用在group by之后。
以上三點就是分組查詢group by的用法及講解。
