HAVING 專門用於分組後對彙總結果進行篩選,是 GROUP BY 的必要伴侶,與行級篩選的 WHERE 本質不同。
SELECT 欄位1, 聚合函數(欄位2)
FROM 資料表
[WHERE 行級條件]
GROUP BY 欄位1
HAVING 聚合條件
[ORDER BY ...];
| 維度 | WHERE | HAVING |
|---|---|---|
| 作用階段 | 分組前(行級) | 分組後(組級) |
| 可用運算元 | 資料欄位、常數、函數 | 聚合函數(SUM, COUNT, AVG...)+ 分組欄位 |
| 執行順序 | FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY | |
| 典型用途 | 過濾來源資料 | 過濾彙總結果 |
情境:Store_Information 表含 store_name, sales,查詢總銷售額超過 1500 的店舖。
SELECT store_name, SUM(sales) AS TotalSales
FROM Store_Information
GROUP BY store_name
HAVING SUM(sales) > 1500;
結果:
| store_name | TotalSales |
|---|---|
| Los Angeles | $1800 |
HAVING SUM(sales) > 1000 AND COUNT(*) > 5WHERE sales_date > '2023-01-01' GROUP BY store_name HAVING SUM(sales) > 5000(先縮小資料集再分組,效能更好)。HAVING COUNT(*) > 100 等同檢查總列數。-- 錯誤:WHERE 不能用聚合函數
SELECT store_name, SUM(sales)
FROM Store_Information
WHERE SUM(sales) > 1500 -- Msg 147, Level 15
GROUP BY store_name;
-- 正確:移至 HAVING
SELECT store_name, SUM(sales)
FROM Store_Information
GROUP BY store_name
HAVING SUM(sales) > 1500;
WHERE 過濾列,HAVING 過濾組;聚合函數找 HAVING,行級條件用 WHERE。
掌握 HAVING,輕鬆實現「各類別前 N 名」、「異常群組偵測」、「KPI 達標統計」等進階分析需求。