聚合查詢,group by,where,having

在查詢過程當中聚合語句(sum,min,max,avg,count)要比having子句優先執行.而where子句在查詢過程當中執行優先級別優先於聚合語句(sum,min,max,avg,count)。
簡單說來:
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
以northwind庫爲例.having條件表達示爲聚合語句。確定的說having子句查詢過程執行優先級別低於聚合語句。
再換句說話說把上面的having換成where則會出錯。統計分組數據時用到聚合語句。
對分組數據再次判斷時要用having。若是不用這些關係就不存在使用having。直接使用where就好了。
having就是來彌補where在分組數據判斷時的不足。由於where執行優先級別要快於聚合語句。
優化

聚合函數,這是必需先講的一種特殊的函數:
例如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子句前看下面這幾個例子吧:
spa

1、顯示每一個地區的總人口數和總面積.
SELECT region, SUM(population), SUM(area)
FROM bbc
GROUP BY region
先以region把返回記錄分紅多個組,這就是GROUP BY的字面含義。分完組後,而後用聚合函數對每組中的不一樣字段(一或多條記錄)做運算。
.net

2、 顯示每一個地區的總人口數和總面積.僅顯示那些面積超過1000000的地區。
SELECT region, SUM(population), SUM(area)
FROM bbc
GROUP BY region
HAVING SUM(area)>1000000
在這裏,咱們不能用where來篩選超過1000000的地區,由於表中不存在這樣一條記錄。相反,HAVING子句可讓咱們篩選成組後的各組數據


where group by having 用法
orm

使用 HAVING 子句選擇行blog

  HAVING 子句對 GROUP BY 子句設置條件的方式與 WHERE 子句和 SELECT 語句交互的方式相似。WHERE 子句搜索條件在進行分組操做以前應用;而 HAVING 搜索條件在進行分組操做以後應用。HAVING 語法與 WHERE 語法相似,但 HAVING 能夠包含聚合函數。HAVING 子句能夠引用選擇列表中出現的任意項。排序

  下面的查詢獲得本年度截止到目前的銷售額超過 $40,000 的出版商:ip

  USE pubsget

  SELECT pub_id, total = SUM(ytd_sales)it

  FROM titles

  GROUP BY pub_id

  HAVING SUM(ytd_sales) > 40000

  下面是結果集:

  pub_id total

  ------ -----------

  0877 44219

  (1 row(s) affected)

  爲了確保對每一個出版商的計算中至少包含六本書,下面示例使用 HAVING COUNT(*) > 5 消除返回的總數小於六本書的出版商:

  USE pubs

  SELECT pub_id, total = SUM(ytd_sales)

  FROM titles

  GROUP BY pub_id

  HAVING COUNT(pub_id) > 5

  下面是結果集:

  pub_id total

  ------ -----------

  0877 44219

  1389 24941

  (2 row(s) affected)

  理解應用 WHERE、GROUP BY 和 HAVING 子句的正確序列對編寫高效的查詢代碼會有所幫助:

  WHERE 子句用來篩選 FROM 子句中指定的操做所產生的行。

  GROUP BY 子句用來分組 WHERE 子句的輸出。

  HAVING 子句用來從分組的結果中篩選行。

  對於能夠在分組操做以前或以後應用的搜索條件,在 WHERE 子句中指定它們更有效。這樣能夠減小必須分組的行數。應當在 HAVING 子句中指定的搜索條件只是那些必須在執行分組操做以後應用的搜索條件。

  Microsoft® SQL Server 2000 查詢優化器可處理這些條件中的大多數。若是查詢優化器肯定 HAVING 搜索條件能夠在分組操做以前應用,那麼它就會在分組以前應用。查詢優化器可能沒法識別全部能夠在分組操做以前應用的 HAVING 搜索條件。建議將全部這些搜索條件放在 WHERE 子句中而不是 HAVING 子句中。

  如下查詢顯示包含聚合函數的 HAVING 子句。該子句按類型分組 titles 表中的行,而且消除只包含一本書的組:

  USE pubs

  SELECT type

  FROM titles

  GROUP BY type

  HAVING COUNT(type) > 1

  下面是結果集:

  type

  ------------------

  business

  mod_cook

  popular_comp

  psychology

  trad_cook

  (5 row(s) affected)

  如下是沒有聚合函數的 HAVING 子句的示例。該子句按類型分組 titles 表中的行,而且消除不是以字母 p 開頭的那些類型。

  USE pubs

  SELECT type

  FROM titles

  GROUP BY type

  HAVING type = '%p%'

  下面是結果集:

  type

  ------------------

  popular_comp

  psychology

  (2 row(s) affected)

  若是 HAVING 中包含多個條件,那麼這些條件將經過 AND、OR 或 NOT 組合在一塊兒。如下示例顯示如何按出版商分組 titles,只包括那些標識號大於 0800、支付的總預付款已超過 $15,000 且銷售書籍的平均價格小於 $20 的出版商。

  SELECT pub_id, SUM(advance) AS AmountAdvanced,

  AVG(price) AS AveragePrice

  FROM pubs.dbo.titles

  WHERE pub_id > '0800'

  GROUP BY pub_id

  HAVING SUM(advance) > 15000

  AND AVG(price) < 20

  ORDER BY 能夠用來爲 GROUP BY 子句的輸出排序。下面的示例顯示使用 ORDER BY 子句以定義返回 GROUP BY 子句中的行的順序:

  SELECT pub_id, SUM(advance) AS AmountAdvanced,

  AVG(price) AS AveragePrice

  FROM pubs.dbo.titles

  WHERE pub_id > '0800'

  AND price >= 5

  GROUP BY pub_id

  HAVING SUM(advance) > 15000

  AND AVG(price) < 20

  ORDER BY pub_id DESC

相關文章
相關標籤/搜索