摘要:本教學介紹 SQL HAVING 子句,它允許您為 GROUP BY 子句彙總的分組指定條件。
SQL HAVING 子句簡介
在先前的教學中,您已學習如何使用 GROUP BY 子句將資料列彙總成群組,並將彙總函數(例如 MIN、MAX、SUM、COUNT、AVG)套用至每個群組。
若要為群組指定條件,您可以使用 HAVING 子句。
HAVING 子句通常與 SELECT 陳述式中的 GROUP BY 子句一起使用。如果您在沒有 GROUP BY 子句的情況下使用 HAVING 子句,則 HAVING 子句的行為將類似於 WHERE 子句。
以下說明 HAVING 子句的語法
SELECT
column1,
column2,
AGGREGATE_FUNCTION (column3)
FROM
table1
GROUP BY
column1,
column2
HAVING
group_condition;
Code language: SQL (Structured Query Language) (sql)
請注意,HAVING 子句會緊接在 GROUP BY 子句之後。
HAVING 與 WHERE 的比較
WHERE 子句會在資料列由 GROUP BY 子句彙總成分組之前,將條件套用到個別的資料列。然而,HAVING 子句會在資料列彙總成分組之後,將條件套用到群組。
因此,務必注意,HAVING 子句是在 GROUP BY 子句之後套用,而 WHERE 子句則是在 GROUP BY 子句之前套用。
SQL HAVING 子句範例
我們將使用範例資料庫中的 employees 和 departments 資料表來進行示範。

若要取得經理及其直屬下屬,您可以使用 GROUP BY 子句依經理對員工進行分組,並使用 COUNT 函數來計算直屬下屬的人數。
以下查詢說明這個概念
SELECT
manager_id,
first_name,
last_name,
COUNT(employee_id) direct_reports
FROM
employees
WHERE
manager_id IS NOT NULL
GROUP BY manager_id;
Code language: SQL (Structured Query Language) (sql)

若要找出至少有五名直屬下屬的經理,您可以在上述查詢中新增 HAVING 子句,如下所示
SELECT
manager_id,
first_name,
last_name,
COUNT(employee_id) direct_reports
FROM
employees
WHERE
manager_id IS NOT NULL
GROUP BY manager_id
HAVING direct_reports >= 5;
Code language: SQL (Structured Query Language) (sql)

SQL HAVING 與 SUM 函數的範例
以下陳述式會計算公司為每個部門支付的薪資總和,並且僅選取薪資總和在 20000 到 30000 之間的部門。
SELECT
department_id, SUM(salary)
FROM
employees
GROUP BY department_id
HAVING SUM(salary) BETWEEN 20000 AND 30000
ORDER BY SUM(salary);
Code language: SQL (Structured Query Language) (sql)

SQL HAVING 與 MIN 函數的範例
若要找出最低薪資大於 10000 的員工所屬的部門,您可以使用以下查詢
SELECT
e.department_id,
department_name,
MIN(salary)
FROM
employees e
INNER JOIN departments d ON d.department_id = e.department_id
GROUP BY
e.department_id
HAVING
MIN(salary) >= 10000
ORDER BY
MIN(salary);
Code language: SQL (Structured Query Language) (sql)

查詢的運作方式。
- 首先,使用 GROUP BY 子句依部門對員工進行分組。
- 第二,使用 MIN 函數找出每個群組的最低薪資。
- 第三,將條件套用到 HAVING 子句。
SQL HAVING 子句與 AVG 函數的範例
若要找出員工平均薪資介於 5000 到 7000 之間的部門,您可以使用 AVG 函數,如下列查詢所示
SELECT
e.department_id,
department_name,
ROUND(AVG(salary), 2)
FROM
employees e
INNER JOIN departments d ON d.department_id = e.department_id
GROUP BY
e.department_id
HAVING
AVG(salary) BETWEEN 5000
AND 7000
ORDER BY
AVG(salary);
Code language: SQL (Structured Query Language) (sql)

在本教學中,您已學習如何使用 SQL HAVING 子句將條件套用到群組。