SQL HAVING

HAVING 篩選 (SQL HAVING)

這篇 SQL HAVING 教學將帶你認識 HAVING 子句的基本概念與用法。HAVING 用來對 GROUP BY 分組後的結果進行條件篩選,通常搭配聚合函數(如 COUNT、SUM、AVG、MIN、MAX)一起使用。

你可能會好奇,WHERE 不是也能篩選資料嗎?沒錯,但 WHERE 是在分組之前篩選個別資料列,而 HAVING 則是在分組之後篩選分組結果。當你需要根據聚合函數的計算結果來篩選時,就必須使用 HAVING

以下是 WHEREHAVING 的主要差異:

比較項目WHEREHAVING
篩選時機分組前(GROUP BY 之前)分組後(GROUP BY 之後)
篩選對象個別資料列分組後的結果
能否使用聚合函數不能可以
常見搭配SELECT、UPDATE、DELETEGROUP BY + 聚合函數

HAVING 語法 (SQL HAVING Syntax)

SELECT column_name, aggregate_function(column_name)
FROM table_name
WHERE condition
GROUP BY column_name
HAVING aggregate_function(column_name) condition;

說明:

關鍵字說明
SELECT指定要查詢的欄位與聚合函數
FROM指定資料來源的資料表
WHERE(選填)在分組前先篩選資料列
GROUP BY指定用來分組的欄位
HAVING對分組後的聚合結果進行條件篩選

HAVING 用法 (Example)

假設我們有一個員工資料表 employees 如下(若需了解如何建立資料表,請參考 CREATE TABLE 教學):

NameDepartmentSalary
張一業務部35000
王二資訊部42000
李三業務部38000
趙四資訊部45000
陳五人資部40000
林六業務部36000
黃七資訊部48000

篩選員工人數 >= 2 的部門

使用 HAVING 搭配 COUNT() 函數,可以篩選出員工人數大於或等於 2 的部門。

SELECT Department, COUNT(*) AS headcount
FROM employees
GROUP BY Department
HAVING COUNT(*) >= 2;

查詢結果如下:

Departmentheadcount
業務部3
資訊部3

因為人資部只有 1 位員工,不符合 COUNT(*) >= 2 的條件,所以被篩選掉了。

篩選平均薪資 >= 40000 的部門

使用 HAVING 搭配 AVG() 函數,可以篩選出平均薪資大於或等於 40000 的部門。

SELECT Department, AVG(Salary) AS avg_salary
FROM employees
GROUP BY Department
HAVING AVG(Salary) >= 40000;

查詢結果如下:

Departmentavg_salary
資訊部45000
人資部40000

篩選薪資總和 > 100000 的部門

使用 HAVING 搭配 SUM() 函數,可以篩選出薪資總和超過 100000 的部門。

SELECT Department, SUM(Salary) AS total_salary
FROM employees
GROUP BY Department
HAVING SUM(Salary) > 100000;

查詢結果如下:

Departmenttotal_salary
業務部109000
資訊部135000

搭配 WHERE 與 HAVING 一起使用

WHEREHAVING 可以在同一個查詢中同時使用。WHERE 先篩選個別資料列,篩選後的結果再進行 GROUP BY 分組,最後由 HAVING 篩選分組結果。

例如,先排除薪資低於 36000 的員工,再篩選出平均薪資 >= 40000 的部門:

SELECT Department, COUNT(*) AS headcount, AVG(Salary) AS avg_salary
FROM employees
WHERE Salary >= 36000
GROUP BY Department
HAVING AVG(Salary) >= 40000;

查詢結果如下:

Departmentheadcountavg_salary
資訊部345000
人資部140000

執行順序為:先由 WHERE 排除薪資低於 36000 的張一(業務部,35000),接著 GROUP BY 對剩餘資料進行分組,最後 HAVING 篩選出平均薪資 >= 40000 的部門。業務部因為平均薪資為 37000((38000 + 36000) / 2),不符合條件而被排除。

HAVING 搭配多個條件

HAVING 子句中可以使用 ANDOR 來組合多個條件,就像 WHERE 一樣。

SELECT Department, COUNT(*) AS headcount, AVG(Salary) AS avg_salary
FROM employees
GROUP BY Department
HAVING COUNT(*) >= 2 AND AVG(Salary) >= 40000;

查詢結果如下(只有同時滿足員工人數 >= 2 且平均薪資 >= 40000 的部門):

Departmentheadcountavg_salary
資訊部345000

搭配 ORDER BY 排序結果

篩選後的結果可以搭配 ORDER BY 進行排序。完整的查詢語句執行順序為:WHEREGROUP BYHAVINGORDER BY

SELECT Department, COUNT(*) AS headcount, SUM(Salary) AS total_salary
FROM employees
GROUP BY Department
HAVING COUNT(*) >= 2
ORDER BY total_salary DESC;

查詢結果如下:

Departmentheadcounttotal_salary
資訊部3135000
業務部3109000

SQL 語句執行順序

了解 SQL 語句的執行順序,有助於理解 WHEREHAVING 的差異:

順序子句說明
1FROM指定資料來源
2WHERE篩選個別資料列
3GROUP BY將資料分組
4HAVING篩選分組結果
5SELECT選取要顯示的欄位
6ORDER BY排序結果

從執行順序可以看出,WHERE 在第 2 步執行(分組前),而 HAVING 在第 4 步執行(分組後),這就是為什麼 WHERE 不能使用聚合函數,而 HAVING 可以。

延伸閱讀