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

SQL HAVING 與 WHERE 深度解析:執行順序、聚合過濾、效能差異與實戰案例

     編輯:關於SqlServer

WHERE 與 HAVING 同為過濾子句,但作用階段、作用對象、可用函數截然不同。搞清二者邊界是編寫高效聚合查詢的關鍵。

核心差異對比表

維度WHEREHAVING
執行順序第 2 步 (FROM/JOIN 後,GROUP BY 前)第 4 步 (GROUP BY 聚合後,SELECT 前)
作用對象單行 (輸入行)分組 (聚合後的組)
可用聚合函數不可用可用 (SUM, COUNT, AVG, MIN, MAX 等)
可用列表列、衍生列、別名(視資料庫)分組列、聚合表達式
效能特徵早期過濾,減少參與聚合的行數晚期過濾,聚合完成後再篩選組

標準查詢執行順序

1. FROM / JOIN          -- 確定數據源
2. WHERE                -- 行級過濾
3. GROUP BY             -- 分組
4. HAVING               -- 組級過濾 (可用聚合)
5. SELECT               -- 投影列、別名
6. ORDER BY             -- 排序
7. OFFSET / FETCH       -- 分頁

實戰案例:BBC 國家表

-- 表結構: name, region, area, population, gdp

案例 1:各區域總人口、總面積

SELECT Region, SUM(Population) AS TotalPop, SUM(Area) AS TotalArea
FROM BBC
GROUP BY Region;

案例 2:僅顯示總面積 > 1,000,000 的區域

SELECT Region, SUM(Population), SUM(Area)
FROM BBC
GROUP BY Region
HAVING SUM(Area) > 1000000;  -- 必須用 HAVING,因無單行 Area > 1000000

錯誤寫法:WHERE SUM(Area) > 1000000 → 報錯「聚合函數不允許在 WHERE 中」。

案例 3:區域人口 > 1億 且 面積 > 100萬

SELECT Region, SUM(Population) AS Pop, SUM(Area) AS Area
FROM BBC
GROUP BY Region
HAVING SUM(Population) > 100000000 AND SUM(Area) > 1000000;

MySQL 實戰:查找重復 Email

-- 步驟 1: 分組計數
SELECT Email, COUNT(*) AS Cnt FROM Edm_User GROUP BY Email;

-- 步驟 2: 過濾重複 (Cnt > 1)
SELECT Email, COUNT(*) AS Cnt 
FROM Edm_User 
GROUP BY Email 
HAVING COUNT(*) > 1;  -- 等價 HAVING Cnt > 1 (MySQL 支援別名)

效能優化鐵律

能在 WHERE 解決的,絕不拖到 HAVING。

-- 低效:先分組聚合全表,再過濾
SELECT Region, COUNT(*) FROM BBC GROUP BY Region HAVING Region = 'Asia';

-- 高效:先過濾行,再分組聚合
SELECT Region, COUNT(*) FROM BBC WHERE Region = 'Asia' GROUP BY Region;

前者掃描全表、聚合所有區域、最後丟棄非 Asia 組;後者僅掃描 Asia 區域行,I/O、CPU、內存均大幅降低。

進階場景:HAVING 無聚合函數(罕見但合法)

SELECT Region, COUNT(*) AS Cnt
FROM BBC
GROUP BY Region
HAVING Region LIKE 'A%';  -- 僅用分組列過濾,語法合法但建議移到 WHERE

總結速記

  • WHERE = 行過濾器,前置,不可用聚合。
  • HAVING = 組過濾器,後置,專用聚合。
  • 查詢寫法順序:WHERE → GROUP BY → HAVING。
  • 效能口訣:早過濾、少聚合、快出結果。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved