MySQL 速習チュートリアル

MySQL HAVING 句

1. MySQL HAVING 句の概要

HAVING 句は、集約関数(Aggregate Functions)に基づいて GROUP BY クエリの結果をフィルタリングするために使用されます。

行のグループ化が実行されるに個々の行をフィルタリングする WHERE 句とは異なり、HAVING 句は集約が実行されたにグループに対してフィルタリングを行います。

1.1 HAVING の基本構文

SELECT column1, aggregate_function(column2), column3, ...
FROM table_name
WHERE condition
GROUP BY column1, column3
HAVING condition  -- グループ化されたデータに対する条件
ORDER BY column_name;

2. デモ用データベース

以下は、Northwind サンプルデータベースの「Customers(顧客)」テーブルからの抜粋です。

CustomerIDCustomerNameContactNameAddressCityPostalCodeCountry
1Alfreds FutterkisteMaria AndersObere Str. 57Berlin12209Germany
2Ana Trujillo Emparedados y heladosAna TrujilloAvda. de la Constitución 2222México D.F.05021Mexico
3Antonio Moreno TaqueríaAntonio MorenoMataderos 2312México D.F.05023Mexico
4Around the HornThomas Hardy120 Hanover Sq.LondonWA1 1DPUK
5Berglunds snabbköpChristina BerglundBerguvsvägen 8LuleåS-958 22Sweden

3. MySQL HAVING の使用例

次の SQL は、国(Country)ごとの顧客数を返しますが、顧客数が 5 人を超える国のみを取得します。

-- 顧客数が 5 人より多い国だけを抽出します
SELECT Country, COUNT(CustomerID) AS "顧客数"
FROM Customers
GROUP BY Country
HAVING COUNT(CustomerID) > 5;

次の SQL は、国ごとの顧客数を返し、顧客数が 5 人を超える国のみを顧客数の多い順(降順)にソートして表示します。

-- フィルタリング後に、集約結果(COUNT)に基づいてソートを実行します
SELECT Country, COUNT(CustomerID) AS "顧客数"
FROM Customers
GROUP BY Country
HAVING COUNT(CustomerID) > 5
ORDER BY COUNT(CustomerID) DESC;

4. 追加のデモ用データベース

以下の例では、Northwind サンプルデータベースの「Orders(注文)」テーブルと「Employees(従業員)」テーブルを使用します。

「Orders」テーブルの抜粋:

OrderIDCustomerIDEmployeeIDOrderDateShipperID
102489051996-07-043
102498161996-07-051
102503441996-07-082

「Employees」テーブルの抜粋:

EmployeeIDLastNameFirstNameBirthDatePhotoNotes
1DavolioNancy1968-12-08EmpID1.pic教育背景にはBAが含まれます...
2FullerAndrew1952-02-19EmpID2.picAndrewはBTSを受け取りました...
3LeverlingJanet1963-08-30EmpID3.picJanetはBSの学位を持っています...

5. HAVING の応用例

次の SQL は、10 件を超える注文を登録した従業員を返します。

-- JOIN を使用して従業員名を取得し、注文数で絞り込みます
SELECT Employees.LastName, COUNT(Orders.OrderID) AS NumberOfOrders
FROM (Orders
INNER JOIN Employees ON Orders.EmployeeID = Employees.EmployeeID)
GROUP BY LastName
HAVING COUNT(Orders.OrderID) > 10;

次の SQL は、従業員 "Davolio" または "Fuller" が 25 件を超える注文を登録しているかどうかを返します。

-- WHERE 句で特定の従業員に絞り込んだ後、集約結果を HAVING でさらに判定します
SELECT Employees.LastName, COUNT(Orders.OrderID) AS NumberOfOrders
FROM Orders
INNER JOIN Employees ON Orders.EmployeeID = Employees.EmployeeID
WHERE LastName = 'Davolio' OR LastName = 'Fuller'
GROUP BY LastName
HAVING COUNT(Orders.OrderID) > 25;