天天看點

資料庫 sql語句中where和having的差別 、having的使用、SQL中Group By的使用

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、原始表

資料庫 sql語句中where和having的差別 、having的使用、SQL中Group By的使用

3、簡單Group By

示例1

select 類别, sum(數量) as 數量之和
from A
group by 類别      

傳回結果如下表,實際上就是分類彙總。

資料庫 sql語句中where和having的差別 、having的使用、SQL中Group By的使用

4、Group By 和 Order By

示例2

select 類别, sum(數量) AS 數量之和
from A
group by 類别
order by sum(數量) desc      

傳回結果如下表

資料庫 sql語句中where和having的差別 、having的使用、SQL中Group By的使用

在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語句的後面,作為分組的依據;要麼就要被包含在聚合函數中。

資料庫 sql語句中where和having的差別 、having的使用、SQL中Group By的使用

6、Group By All

示例4

select 類别, 摘要, sum(數量) as 數量之和
from A
group by all 類别, 摘要      

示例4中則可以指定“摘要”字段,其原因在于“多列分組”中包含了“摘要字段”,其執行結果如下表

資料庫 sql語句中where和having的差別 、having的使用、SQL中Group By的使用

“多列分組”實際上就是就是按照多列(類别+摘要)合并後的值進行分組,示例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      

執行結果:

資料庫 sql語句中where和having的差別 、having的使用、SQL中Group By的使用

示例10:Compute

select *
from A
where 數量>8
compute max(數量),min(數量),avg(數量)      

執行結果如下:

資料庫 sql語句中where和having的差別 、having的使用、SQL中Group By的使用

compute子句能夠觀察“查詢結果”的資料細節或統計各列資料(如例10中max、min和avg),傳回結果由select清單和compute統計結果組成。

示例11:Compute By

select *
from A
where 數量>8
order by 類别
compute max(數量),min(數量),avg(數量) by 類别      

執行結果如下:

資料庫 sql語句中where和having的差別 、having的使用、SQL中Group 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并不支援