1. 程式人生 > >SQL系列(八)—— 分組(group by)

SQL系列(八)—— 分組(group by)

出了 常用 sql select group 數量 通過 報錯 mysql

在很多場景時,需要對數據按照某條件進行分組統計其數量、平均值等等。有這種需求,SQL自然也有解決方式。

在SQL中通過group by子句對結果按某條件進行分組。語法:

select count(column1), columnJ from table_name group by columnJ;

group by是後接檢索的列或者表達式。表示對該列或者表達式的數據進行分組,該列上或者表達式相同的數據放在同一組。

group by使用的註意點:

  • group by必須作用在檢索列上或者表達式上
  • group by可以作用在多個列上,會按照列的順序,進行逐層分組
  • group by後的列是select的子句中的檢索列或者表達式
  • group by會將列為NULL值的作為一組

註:大多數情況的場景都是使用group by進行分組,然後對分組的數據進行聚合統計。很少是分組後取某組中的個別列的數據。如:

select name, age from teacher group by age;

select子句中包含了非聚合的列name(這屬於取分組結果中個別列的數據情況)。
在Mysql中默認模式:ONLY_FULL_GROUP_BY下,如果執行以上SQL會報錯;可以將其關閉,如果再執行以上SQL,mysql將會取分組中的每組的第一行數據作為結果集。

通過看下面的示例,來熟悉下group by:

select age, count(name) as group_count from teacher group by age;

以上的SQL表示的含義:按年齡分組統計每個年齡的老師數量,執行結果:

age group_count
25 2
26 2
27 1
28 1
29 1

再來看一個例子:

select name, max(age), min(age) from person group by name;

以上SQL表示,按照姓名分組統計,找出每組中最大年齡,最小年齡的人,執行結果如下

name max min
xiaohei 20 29
xiaohong 28 26
xiaolan 67 56

以上的例子足以理解group by。group by即對結果集進行按條件進行分組,然後常進行聚合處理。
但是往往仍需要對分組後的結果進行過濾處理,SQL中使用另外一個子句HAVING對group by的分組結果進行過濾處理,如下:

select age, count(name) as group_count from teacher group by age having age < 27;

執行結果

age count
25 2
26 2

對分組結果進行過濾,只檢索出分組中年齡小於27的組。

在看到having時,不免聯系到where子句,下面總結下他們的異同點:

相同點 1.having和where都是對結果按照條件過濾;
2.在使用where的地方都可以使用having(不常用);
不同點 1.針對的過濾數據不一樣,having主要是用來過濾分組,where主要是過濾表中數據行;
2.having和where子句的位置不一樣,having在group by後,where在from子句後;
3.having通常配合group by使用;

那麽在有having過濾情況下是否還能使用where呢?
根據上表中不同點1可以看出,是可以的。where是對數據行過濾,然後再對過濾後的行進行分組,再對分組進行having過濾。

下表列出了SQL的執行順序:

子句 說明 使用場景
select 查詢數據 在db數據檢索時使用
from 檢索的表 檢索時使用
where 過濾數據的條件 需要對數據進行篩選時
gropu by 分組select的結果集 需要聚合統計時常用
having 過濾分組 對分組進行過濾時需要
order by 排序結果集 需要按照某種順序展示數據
參考

《SQL必知必會》

SQL系列(八)—— 分組(group by)