首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

SQL WHERE 與 HAVING 差異深度解析:從執行順序到實戰場景

     編輯:MySQL 資料庫相關知識

WHERE 與 HAVING 都是設定查詢條件,但作用階層、支援函數、適用場景截然不同。本文從查詢執行流程、語法限制、實戰案例三個維度,徹底釐清兩者差異,助您寫出正確且高效的分組查詢。

核心差異一覽表

維度WHEREHAVING
作用對象單筆資料列分組後的群組
執行順序GROUP BY 之前GROUP BY 之後
可用聚合函數不可可(SUM、COUNT 等)
典型用途資料清洗、篩選基礎列分組品質控管、彙總條件

查詢執行流程圖解

1. FROM / JOIN          → 產生基礎資料集
2. WHERE                → 列級過濾(移除不符合條件的列)
3. GROUP BY             → 依指定欄位分組
4. 聚合函數              → 計算每組 SUM/COUNT/AVG...
5. HAVING               → 組級過濾(移除不符合彙總條件的組)
6. SELECT               → 投影輸出欄位
7. ORDER BY             → 排序最終結果

實戰案例演示(以 Northwind Employees 表為例)

案例 1:列級條件 → 必須用 WHERE

需求:統計每位主管名下員工數,但只統計受僱日期在 1993 年後的員工。

SELECT ReportsTo AS ManagerID, COUNT(*) AS EmpCount
FROM Employees
WHERE HireDate > '1993-01-01'   -- 列級條件,在分組前過濾
GROUP BY ReportsTo;

案例 2:組級條件 → 必須用 HAVING

需求:找出名下員工超過 4 人的主管。

SELECT ReportsTo AS ManagerID, COUNT(*) AS EmpCount
FROM Employees
GROUP BY ReportsTo
HAVING COUNT(*) > 4;   -- 組級條件,針對聚合結果過濾

案例 3:混合使用 WHERE + HAVING

需求:統計 1993 年後受僱員工的主管分布,且只顯示名下≥3人的主管。

SELECT ReportsTo AS ManagerID, COUNT(*) AS EmpCount
FROM Employees
WHERE HireDate > '1993-01-01'   -- 先縮減資料集
GROUP BY ReportsTo
HAVING COUNT(*) >= 3;           -- 再篩選分組結果

常見錯誤與修正

錯誤寫法錯誤原因正確寫法
HAVING HireDate > '1993-01-01'HireDate 非聚合欄位,不可用於 HAVING移至 WHERE
WHERE COUNT(*) > 4聚合函數不可用於 WHERE改用 HAVING COUNT(*) > 4
GROUP BY ManagerName HAVING ManagerName = 'John'分組鍵值過濾應用 WHEREWHERE ManagerName = 'John' GROUP BY ManagerName

聚合函數快速回顧

  • SUM(col):加總
  • COUNT(col):非 NULL 筆數;COUNT(*) 含 NULL
  • AVG(col):平均
  • MAX/MIN(col):極值
  • GROUP BY region 使聚合函數按 region 分組計算,每組僅回傳一列

進階場景:HAVING 配合子查詢

需求:找出總銷售額超過全公司平均銷售額的業務員。

SELECT SalesPersonID, SUM(TotalDue) AS TotalSales
FROM SalesOrderHeader
GROUP BY SalesPersonID
HAVING SUM(TotalDue) > (SELECT AVG(TotalSales) FROM
    (SELECT SalesPersonID, SUM(TotalDue) AS TotalSales
     FROM SalesOrderHeader GROUP BY SalesPersonID) t);

各資料庫支援度備註

  • 標準 SQL:全支援
  • MySQL:允許 HAVING 使用別名(HAVING EmpCount > 4),但建議寫完整聚合以相容遷移
  • PostgreSQL / SQL Server / Oracle:嚴格遵循標準,HAVING 不可用 SELECT 別名
  • SQLite:支援基本用法

記憶口訣

WHERE 過濾列,HAVING 過濾組;
聚合函數不能進 WHERE,分組之後才能用 HAVING。

掌握執行順序與作用層級,即可在複雜報表查詢中精準選擇 WHERE 或 HAVING,避免語法錯誤與邏輯漏洞,撰寫出既正確又高效的 SQL。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved