Oracle SQLでデータを集計するとき、GROUP BY句を使ってデータをグループ化する場面があります。しかし、グループ化した後の集計結果に対して条件を指定したい場合、WHERE句では思ったような絞り込みができません。
GROUP BYによって作成された集計結果を対象に条件を指定するには、専用のHAVING句を使用します。この記事では、HAVING句の役割やWHERE句との違い、具体的なSQL例を使った使い分けについて分かりやすく解説します。
GROUP BY後の集計結果を絞り込むにはHAVING句を使う
Oracle SQLでは、GROUP BY句でデータをまとめた後、そのグループごとの集計結果に条件を指定する場合にHAVING句を使用します。
例えば、商品の販売データから「商品ごとの売上合計」を計算し、その中から売上合計が100万円以上の商品だけを表示したい場合、WHERE句ではなくHAVING句を使います。
基本的な構文は以下のようになります。
SELECT グループ化する列, 集計関数
FROM テーブル名
GROUP BY グループ化する列
HAVING 集計結果に対する条件;
WHERE句とHAVING句の違い
WHERE句とHAVING句はどちらも条件指定に使われますが、適用されるタイミングが異なります。
WHERE句はGROUP BYによる集計を行う前の元データに対して条件を適用します。一方、HAVING句はGROUP BYでグループ化や集計を行った後の結果に対して条件を適用します。
例えば、売上テーブルから2025年のデータだけを対象にして、店舗ごとの売上合計が100万円以上の店舗を探す場合は、WHERE句とHAVING句を組み合わせて使用します。
SELECT 店舗名, SUM(金額)
FROM 売上
WHERE 売上日 >= DATE ‘2025-01-01’
GROUP BY 店舗名
HAVING SUM(金額) >= 1000000;
HAVING句で集計関数を条件に利用する方法
HAVING句が特に活用されるのは、COUNTやSUM、AVGなどの集計関数を条件として使用する場合です。
例えば、購入回数が10回以上ある顧客だけを抽出したい場合、購入回数はGROUP BY後に計算される値なのでHAVING句を使用します。
具体例として、顧客IDごとの注文数を調べる場合は以下のようになります。
SELECT 顧客ID, COUNT(*) AS 注文回数
FROM 注文履歴
GROUP BY 顧客ID
HAVING COUNT(*) >= 10;
このSQLでは、まず顧客IDごとに注文履歴をまとめ、その後で注文回数が10回以上のグループだけを取得しています。
HAVING句を使う時の注意点
HAVING句は便利ですが、すべての条件をHAVING句に書けばよいわけではありません。集計前に絞り込める条件はWHERE句で指定する方が効率的です。
例えば、特定の地域のデータだけを集計したい場合はWHERE句で先に対象データを減らします。その後、集計結果に対する条件をHAVING句で指定します。
大量のデータを扱うシステムでは、WHERE句で不要なデータを早い段階で除外することで、処理速度の向上につながります。
GROUP BYとHAVINGを組み合わせた実践例
例えば、社員ごとの平均給与を計算し、平均給与が50万円以上の社員グループを表示したい場合を考えます。
SQLでは以下のように記述できます。
SELECT 部署名, AVG(給与) AS 平均給与
FROM 社員
GROUP BY 部署名
HAVING AVG(給与) >= 500000;
この場合、AVG(給与)という集計結果を条件にしているため、WHERE句ではなくHAVING句を使用します。
GROUP BYで作成されたグループそのものを評価する場合はHAVING句を使う、と覚えておくと判断しやすくなります。
まとめ
Oracle SQLでGROUP BYによるグループ化後の集計結果に対して絞り込み条件を適用する場合は、HAVING句を使用します。
WHERE句は集計前のデータを絞り込むために使い、HAVING句はSUMやCOUNT、AVGなどの集計結果に条件を指定するために使います。
SQLを書く際は、「この条件は集計する前に判断できるのか、それとも集計した後でしか判断できないのか」を考えることで、WHERE句とHAVING句を正しく使い分けられるようになります。


コメント