概要:このチュートリアルでは、GROUP BY句で集計されたグループに条件を指定できるSQL HAVING句について説明します。
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 vs. 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)

直属の部下が5人以上の管理者を見つけるには、上記のクエリに次のように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)

SUM関数を使用したSQL HAVINGの例
次のステートメントは、会社が各部門に支払う給与の合計を計算し、給与の合計が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)

MIN関数を使用したSQL HAVINGの例
最低給与が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関数を使用して、グループごとの最低給与を見つけます。
- 3番目に、HAVING句に条件を適用します。
AVG関数を使用したSQL HAVING句の例
従業員の平均給与が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句を使用してグループに条件を適用する方法を学びました。