首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL 中 HAVING 與 WHERE 條件篩選本質差異:聚合前 vs 聚合後

     編輯:關於SqlServer

核心結論先行

WHERE:聚合前過濾資料列,不可使用聚合函數。
HAVING:聚合後過濾分組結果,可使用聚合函數。

聚合函數速查

函數說明忽略 NULL
AVG平均值是
COUNT行數/非空值數COUNT(*) 不忽略,COUNT(col) 忽略
MAX最大值是
MIN最小值是
SUM總和是

GROUP BY 機制

GROUP BY 將結果集按指定欄位分組,每組僅輸出一行。SELECT 列表中非分組欄位必須包裹在聚合函數中。

SELECT region, SUM(population), SUM(area)
FROM bbc
GROUP BY region

→ 依 region 分組,每組輸出 region、人口總和、面積總和。

實戰對比:WHERE vs HAVING

場景:顯示人口超過 1,000,000 的地區總人口與總面積

❌ 錯誤寫法(WHERE 用聚合):

SELECT region, SUM(population), SUM(area)
FROM bbc
WHERE SUM(population) > 1000000  -- 錯誤:WHERE 階段尚未聚合
GROUP BY region

✅ 正確寫法(HAVING 過濾聚合結果):

SELECT region, SUM(population), SUM(area)
FROM bbc
GROUP BY region
HAVING SUM(population) > 1000000

原因:原始表無單行人口超百萬記錄,必須先分組聚合再過濾。

結合 WHERE + HAVING 雙層過濾

SELECT region, SUM(population) AS total_pop
FROM bbc
WHERE area > 1000000          -- 聚合前:先過濾大面積國家
GROUP BY region
HAVING SUM(population) > 50000000  -- 聚合後:再過濾大人口地區
ORDER BY total_pop DESC

執行順序口訣

FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY

WHERE 在 GROUP BY 前,HAVING 在 GROUP BY 後 —— 這就是能否用聚合函數的根本原因。

常見誤區

  • 誤區 1: 「HAVING 只能用於 GROUP BY 後」→ 事實上無 GROUP BY 時整張表視為一組,HAVING 仍可用(等同 WHERE 但可用聚合)。
  • 誤區 2: 「WHERE 不能用子查詢」→ WHERE 可用子查詢,甚至可在子查詢中用聚合。
  • 誤區 3: 「HAVING 效能差」→ HAVING 過濾的是已聚合的少量組,通常比 WHERE 過濾大量明細行更快。

總結

  • 先想「要不要聚合」:要聚合才用 HAVING,單純行過濾用 WHERE。
  • WHERE 減少進入聚合的資料量(效能關鍵),HAVING 精準篩選業務指標。
  • 良習:WHERE 寫靜態條件(日期範圍、狀態碼),HAVING 寫動態指標(銷售額、筆數、轉換率)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved