group by 和聚合函式
group by做為分組來使用,後面為條件,可以有多個條件,條件相同的為一組,配合聚合函式進行相關統計。在不同資料庫中用法稍有不同,這裡只測試mysql和oracle。
1.準備好一張資料表:
mysql oracle
2.首先以name為分組條件:
1 SELECT * FROM person 2 GROUP BY `name`;
在mysql中執行結果如下:
分析:
在mysql中沒有強調select指定的欄位必須屬於group by後的條件。若符合條件的欄位有多個,則只顯示第一次出現的欄位。比如:以name為dd分組,id為1,2,3,4,5,但只顯示1.同理,age也只顯示1.
然後,雖然這種查詢在語法上通過了,但結果並沒有什麼意義,因為其他欄位並非需要的準確值。這在oracle中就行不通了。
在oracle中執行結果如下:
分析:
oracle指出,select查詢欄位未包含在group by 的條件中。推測,首先通過select * from person可以看到oracle中id並不是升序,或者說沒有預設升序。也就是查詢的結果是不確定的,hash?這可能涉及到在磁碟的儲存等等,這裡不去深究。因此,並不能確認第一次查出來的欄位的值,而且分組後不是條件的值被合併後沒有意義。
結論:
group by語句中select指定的欄位必須是“分組依據欄位”。
因此,只能這樣查詢:
SELECT name FROM person GROUP BY name;
結果一致:。
3.以name,age為查詢依據,多條件分組
1 SELECT name,age FROM person 2 GROUP BY name,age;
結果:
mysql oracle
顯然,兩組的查詢策略是不同的。但最終結果是相同的。都是以條件組合的笛卡爾積。也就是每個條件都一一對應。
分組依據為多條件組合成一個條件,當組合條件相同時為一組。因此,dd:1和dd:2分為兩組。
4.新增聚合函式
聚合函式有如下幾種:
函式 | 作用 | 支援性 |
---|---|---|
sum(列名) | 求和 | |
max(列名) | 最大值 | |
min(列名) | 最小值 | |
avg(列名) | 平均值 | |
first(列名) | 第一條記錄 | 僅Access支援 |
last(列名) | 最後一條記錄 | 僅Access支援 |
count(列名) | 統計記錄數 | 注意和count(*)的區別 |
首先,要明白聚合函式的用法。比如,count(列欄位值),統計該欄位值出現的次數:
1 SELECT name,COUNT(*) 2 from person 3 GROUP BY name;
結果為:。
分析:
首先進行分組工作,group by name,這時8條資料被分成兩組:dd和mm;然後count的作用就是統計每組裡面的個數,分別是5和3.
更直觀的例子:
SELECT * FROM person;
1 SELECT count(name) from person;
,count(name)為統計所有的name數量,同樣的結果為count(1),count(*).
5.where 和 having
- where 子句的作用是在對查詢結果進行分組前,將不符合where條件的行去掉,即在分組之前過濾資料,where條件中不能包含聚組函式,使用where條件過濾出特定的行。
- having 子句的作用是篩選滿足條件的組,即在分組之後過濾資料,條件中經常包含聚組函式,使用having 條件過濾出特定的組,也可以使用多個分組標準進行分組。