group by, where, having的使用方法和之間區別
select 後的欄位,必須要麼包含在group by中,要麼包含在having後的聚合函式裡。(?)
1、group by是分組查詢,一般group by是和聚合函式配合使用
group by有一個原則,就是select後面的所有列中,沒有使用聚合函式的列,必須出現在group by後面(重要)
例如:有如下資料庫表:
A B
1 abc
2 bcd
3 dfsa
如果有如下查詢語句(該語句是錯誤的,原因見前面的原則)
select A,B from table group by A
該查詢語句是想得到如下結果(顯然是錯誤的):
A B
abc
1 bcd
dfsa
右邊3條如何變成一條?這裡需要使用聚合函式。
select A,count(B) as 數量 from table group by A;
這樣的結果就是:
A 數量
1 3
2、where
where子句的作用是在對查詢結果進行分組前,將不符合where條件的行去掉,即在分組之前過濾資料,條件中不能包含聚合函式,使用where條件顯示特定的行。
3、having
having子句的作用是篩選滿足條件的組,即在分組之後過濾資料,條件中經常包含聚合函式,使用having條件顯示特定的組,也可以使用多個分組標準進行分組。
having子句被限制於已經在select語句中定義的列和聚合表示式上。通常,你需要通過在having子句中重複聚合函式表示式來引用聚合值,就如你在select語句中做的那樣。
☆:having子句和where有相似之處:都是設定條件的語句。
但是二者也有區別:
在查詢過程中聚合語句(sum,min,max,avg,count)要比having子句優先執行。而where子句在查詢過程中執行優先級別優先於聚合語句。
簡單來說:
where子句:select sum(num) as rmb from order where id > 10; //只有先查詢出id大於10的記錄才能進行聚合語句
having子句:select reportsto as manager,count(*) as reports from employees group by reportsto having count(*) > 4; //having子句查詢過程執行優先級別低於聚合語句。
換句話說:
把上面的having換成where則會出錯。統計分組資料時用到聚合語句。對分組資料再次判斷時要用having。如果不用這些關係就不存在使用having。直接使用where就行了。
having就是用來彌補where在分組資料判斷時的不足。因為where執行優先級別要快於聚合函式。
4、聚合函式
這些函式(SUM,COUNT,MAX,AVG等)和其他函式的根本區別就是它們一般作用在多條記錄上。
select sum(population) from tablename;
這裡的sum作用在所有返回記錄的population欄位上,結果就是該查詢只返回一個結果,即所有國家的總人口數。
通過使用group by子句,可以讓sum和count這些函式對屬於一組的資料起作用。
當你指定group by region時,屬於同一個region的一組資料將只能返回一行值。也就是說,表中所有除region外的欄位,只能通過sum,count等聚合函式運算後返回一個值
having子句可以讓我們篩選成組後的各組資料。
having子句在聚合後對組記錄進行篩選,而where子句在聚合前先篩選記錄,也就是說作用在group by 子句和having子句前。
例子:
a:顯示每個地區的總人口數和總面積
select region, sum(population), sum(area)
from bbc
group by region;
這裡先以region把返回記錄分成多個組,這就是group by的字面含義。分組完成後,用聚合函式對每組中的不同欄位(一條或多條記錄)進行運算。
b:顯示每個地區的總人口數和總面積,僅顯示那些面積超過1000000的地區
select region, sum(population), sum(area)
from bbc
group by region
having sum(area) > 1000000;
在這裡,我們不能使用where來篩選超過1000000的地區,因為表中不存在這樣的一條記錄。相反,having子句可以讓我們篩選成組後的各組資料。