having 和where 都是用來篩選用的
having 是篩選組 而where是篩選記錄
他們有各自的差別
1》當分組篩選的時候 用having
2》其它情況用where
-----------------------------------------------------
用having就一定要和group by連用,
用group by不一有having (它隻是一個篩選條件用的)
-------------------------------------------------------
例子
表結構
部門編号 姓名 工資
1 aa 2000
2 bb 1200
1 cc 2100
2 dd 1800
1 ee 2100
3 ff 8000
2 gg 2200
3 hh 4500
查詢有多個員工的工資不低于2000的部門編号
(就是說如果一個部門的員工大于2000的人數有兩個或兩個以上就查詢出來)
select 部門編号,count(*) from 員工資訊表 where 工資>=2000 group by 部門編号 having count(*)>1
where 針對每一條記錄篩選
而 having 對同一個部門的分組
count(*)>1 計算多于兩個的部門
查詢結果為:我在測試的時候部門是b_id
b_id count(*)
1 3
3 2
--------------------------------------------------------------------------------------------
where和having的執行級别不同
在查詢過程中聚合語句(sum,min,max,avg,count)要比having子句優先執行.而where子句在查詢過程中執行優先級别優先于聚合語句(sum,min,max,avg,count)。
having就是來彌補where在分組資料判斷時的不足。因為where執行優先級别要快于聚合語句。
--------------------------------------------------------------------------------------------
HAVING是先分組再篩選記錄,WHERE在聚合前先篩選記錄.也就是說作用在GROUP BY 子句和HAVING子句前;而 HAVING子句在聚合後對組記錄進行篩選。
作用的對象不同。WHERE 子句作用于表和視圖,HAVING 子句作用于組。WHERE 在分組和聚集計算之前選取輸入行(是以,它控制哪些行進入聚集計算), 而 HAVING 在分組和聚集之後選取分組的行。是以,WHERE 子句不能包含聚集函數; 因為試圖用聚集函數判斷那些行輸入給聚集運算是沒有意義的。 相反,HAVING 子句總是包含聚集函數。(嚴格說來,你可以寫不使用聚集的 HAVING 子句, 但這樣做隻是白費勁。同樣的條件可以更有效地用于 WHERE 階段。)比如說:
select * from tablename where id > 1; 和
select * from tablename having id > 1
這兩者是查詢結果是沒有差別的。不建議使用having
---------------------------------------------------------------------------------------------
HAVING 子句
在 SQL 中增加 HAVING 子句原因是,WHERE 關鍵字無法與合計函數一起使用。
SQL HAVING 文法
SELECT column_name, aggregate_function(column_name)
FROM table_name
WHERE column_name operator value
GROUP BY column_name
HAVING aggregate_function(column_name) operator value
SQL HAVING 執行個體
我們擁有下面這個 "Orders" 表:
O_Id | OrderDate | OrderPrice | Customer |
---|---|---|---|
1 | 2008/12/29 | 1000 | Bush |
2 | 2008/11/23 | 1600 | Carter |
3 | 2008/10/05 | 700 | Bush |
4 | 2008/09/28 | 300 | Bush |
5 | 2008/08/06 | 2000 | Adams |
6 | 2008/07/21 | 100 | Carter |
現在,我們希望查找訂單總金額少于 2000 的客戶。
我們使用如下 SQL 語句:
SELECT Customer,SUM(OrderPrice) FROM Orders
GROUP BY Customer
HAVING SUM(OrderPrice)<2000
結果集類似:
Customer | SUM(OrderPrice) |
---|---|
Carter | 1700 |
現在我們希望查找客戶 "Bush" 或 "Adams" 擁有超過 1500 的訂單總金額。
我們在 SQL 語句中增加了一個普通的 WHERE 子句:
SELECT Customer,SUM(OrderPrice) FROM Orders
WHERE Customer='Bush' OR Customer='Adams'
GROUP BY Customer
HAVING SUM(OrderPrice)>1500
結果集:
Customer | SUM(OrderPrice) |
---|---|
Bush | 2000 |
Adams | 2000 |
-------------------------------------------------------------------------------------------
《===SQL中Group By的使用===》
- 1、概述
- 2、原始表
- 3、簡單Group By
- 4、Group By 和 Order By
- 5、Group By中Select指定的字段限制
- 6、Group By All
- 7、Group By與聚合函數
- 8、Having與Where的差別
- 9、Compute 和 Compute By
1、概述
“Group By”從字面意義上了解就是根據“By”指定的規則對資料進行分組,所謂的分組就是将一個“資料集”劃分成若幹個“小區域”,然後針對若幹個“小區域”進行資料處理。
2、原始表
3、簡單Group By
示例1
select 類别, sum(數量) as 數量之和
from A
group by 類别
傳回結果如下表,實際上就是分類彙總。
4、Group By 和 Order By
示例2
select 類别, sum(數量) AS 數量之和
from A
group by 類别
order by sum(數量) desc
傳回結果如下表
在Access中不可以使用“order by 數量之和 desc”,但在SQL Server中則可以。
5、Group By中Select指定的字段限制
示例3
select 類别, sum(數量) as 數量之和, 摘要
from A
group by 類别
order by 類别 desc
示例3執行後會提示下錯誤,如下圖。這就是需要注意的一點,在select指定的字段要麼就要包含在Group By語句的後面,作為分組的依據;要麼就要被包含在聚合函數中。
6、Group By All
示例4
select 類别, 摘要, sum(數量) as 數量之和
from A
group by all 類别, 摘要
示例4中則可以指定“摘要”字段,其原因在于“多列分組”中包含了“摘要字段”,其執行結果如下表
“多列分組”實際上就是就是按照多列(類别+摘要)合并後的值進行分組,示例4中可以看到“a, a2001, 13”為“a, a2001, 11”和“a, a2001, 2”兩條記錄的合并。
SQL Server中雖然支援“group by all”,但Microsoft SQL Server 的未來版本中将删除 GROUP BY ALL,避免在新的開發工作中使用 GROUP BY ALL。Access中是不支援“Group By All”的,但Access中同樣支援多列分組,上述SQL Server中的SQL在Access可以寫成
select 類别, 摘要, sum(數量) AS 數量之和
from A
group by 類别, 摘要
7、Group By與聚合函數
在示例3中提到group by語句中select指定的字段必須是“分組依據字段”,其他字段若想出現在select中則必須包含在聚合函數中,常見的聚合函數如下表:
函數 | 作用 | 支援性 |
---|---|---|
sum(列名) | 求和 | |
max(列名) | 最大值 | |
min(列名) | 最小值 | |
avg(列名) | 平均值 | |
first(列名) | 第一條記錄 | 僅Access支援 |
last(列名) | 最後一條記錄 | 僅Access支援 |
count(列名) | 統計記錄數 | 注意和count(*)的差別 |
示例5:求各組平均值
select 類别, avg(數量) AS 平均值 from A group by 類别;
示例6:求各組記錄數目
select 類别, count(*) AS 記錄數 from A group by 類别;
示例7:求各組記錄數目
8、Having與Where的差別
- where 子句的作用是在對查詢結果進行分組前,将不符合where條件的行去掉,即在分組之前過濾資料,where條件中不能包含聚組函數,使用where條件過濾出特定的行。
- having 子句的作用是篩選滿足條件的組,即在分組之後過濾資料,條件中經常包含聚組函數,使用having 條件過濾出特定的組,也可以使用多個分組标準進行分組。
示例8
select 類别, sum(數量) as 數量之和 from A
group by 類别
having sum(數量) > 18
示例9:Having和Where的聯合使用方法
select 類别, SUM(數量)from A
where 數量 gt;8
group by 類别
having SUM(數量) gt; 10
9、Compute 和 Compute By
select * from A where 數量 > 8
執行結果:
示例10:Compute
select *
from A
where 數量>8
compute max(數量),min(數量),avg(數量)
執行結果如下:
compute子句能夠觀察“查詢結果”的資料細節或統計各列資料(如例10中max、min和avg),傳回結果由select清單和compute統計結果組成。
示例11:Compute By
select *
from A
where 數量>8
order by 類别
compute max(數量),min(數量),avg(數量) by 類别
執行結果如下:
示例11與示例10相比多了“order by 類别”和“... by 類别”,示例10的執行結果實際是按照分組(a、b、c)進行了顯示,每組都是由改組資料清單和改組數統計結果組成,另外:
- compute子句必須與order by子句用一起使用
- compute...by與group by相比,group by 隻能得到各組資料的統計結果,而不能看到各組資料
在實際開發中compute與compute by的作用并不是很大,SQL Server支援compute和compute by,而Access并不支援