having和where子句的區別
1.作用的對象不同。WHERE 子句作用於表和視圖,HAVING 子句作用於組(group)。
eg:SELECT city FROM weather WHERE temp_lo = (SELECT max(temp_lo) FROM weather);
2.WHERE 在分組和聚集計算之前選取輸入行(因此,它控制哪些行進入聚集計算), 而 HAVING 在分組和聚集之後選取分組的行。 因此,WHERE 子句不能包含聚集函數; 因爲試圖用聚集函數判斷那些行輸入給聚集運算是沒有意義的。 相反,HAVING 子句總是包含聚集函數。 (嚴格說來,你可以寫不使用聚集的 HAVING 子句, 但這樣做只是白費勁。同樣的條件可以更有效地用於 WHERE 階段。)
在前面的例子裏,我們可以在 WHERE 裏應用城市名稱限制,因爲它不需要聚集。 這樣比在 HAVING 裏增加限制更加高效,因爲我們避免了爲那些未通過 WHERE 檢查的行進行分組和聚集計算。以下示例使用的數據庫是MySQL 5。
數據表:student
表結構:
Field Name DataType Len
id int 20
name varchar 25
major varchar 25
score int 20
sex varchar 20
表數據:
編號/姓名/專業/學分/性別
id name major score sex
1 jak Chinese 40 f
2 rain Math 89 m
3 leo Phy 78 f
4 jak Math 76 f
5 rain Chinese 56 m
6 leo Math 97 f
7 jak Phy 45 f
8 jak Draw 87 f
9 leo Chinese 45 f
現在我們要得到一個視圖:
要求查詢性別爲男生,並且列出每個學生的總成績:
SQL:
select s.*,sum(s.score) from student s where sex='f' group by s.name
Result:
id name major score sex sum(s.score)
1 jak Chinese 40 f 248
3 leo Phy 78 f 220
可以看到總共查到有兩組,兩組的學生分別是jak和leo,每一組都是同一個學生,這樣我們就可以使用聚合函數了。
只有使用了group by語句,才能使用如:count()、sum()之類的聚合函數。
下面我們再對上面的結果做進一步的篩選,只顯示總分數大於230的學生:
SQL:
select s.*,sum(s.score) from student s where sex='f' group by s.name having sum(s.score)>230
Result:
id name major score sex sum(s.score)
1 jak Chinese 40 f 248
可見having於where的功能差不多。
結論:
1.WHERE 子句用來篩選 FROM 子句中指定的操作所產生的行。
2.GROUP BY 子句用來分組 WHERE 子句的輸出。
3.HAVING 子句用來從分組的結果中篩選行。