HAVINGでグループ条件

HAVINGでグループ条件 とは

HAVING句を使ってグループ化されたデータに条件を指定する方法を学びます。本レッスンでは、HAVINGでグループ条件 の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。

なぜ重要か

GROUP BY でグループ集計したあと、「合計が 10000 円を超えたカテゴリだけ表示したい」「件数が 5 件以上のグループだけ抽出したい」のように、グループに対して条件を付けたい ことが頻繁にあります。WHERE 句で書きたくなりますが、WHERE は集計前の行に対するフィルタで、集計関数の結果には使えません。集計後のグループに対する フィルタHAVING 句の役割です。

レポートのなかで「上位カテゴリだけ取り出す」「異常値のグループだけアラートで出す」「複数注文した顧客だけ表示する」など、HAVING は実務でとても出番が多い構文です。

基本構文

SQL クエリ

SELECT category, COUNT(*) AS cnt, SUM(price) AS total_price FROM products GROUP BY category HAVING SUM(price) >= 10000 ORDER BY total_price DESC;

HAVING は GROUP BY の後ろに書き、SUM(price) >= 10000 のように 集計関数を含む式 で条件を組みます。WHERE と違って HAVING集計関数 を使える点が最大の特徴です。

WHERE と HAVING の使い分け

両者の違いは「集計の前か後か」だけです。

diagram (will load when visible)

たとえば「価格が 1000 円以上の商品だけを対象に、カテゴリ別合計が 10000 円超のグループを出す」なら、両方を組み合わせて使います。

SQL クエリ

SELECT category, SUM(price) AS total_price FROM products WHERE price >= 1000 GROUP BY category HAVING SUM(price) >= 10000;

WHERE は集計前の絞り込み (price 単体に対する条件)、HAVING は集計後の絞り込み (SUM(price) に対する条件) と分担しています。

代表例 1 合計金額の高いカテゴリだけを抽出

カテゴリ別の合計金額を出し、合計 10000 円以上だけを抽出します。

SQL クエリ

SELECT category, SUM(price) AS total_price FROM products GROUP BY category HAVING SUM(price) >= 10000 ORDER BY total_price DESC;

レポートで「重要カテゴリだけを優先表示」したいときの定番パターンです。

代表例 2 件数が一定以上のグループ

顧客の購入履歴テーブルから「3 回以上購入したユーザだけ」を出すクエリです。

SQL クエリ

SELECT user_id, COUNT(*) AS order_count FROM orders GROUP BY user_id HAVING COUNT(*) >= 3 ORDER BY order_count DESC;

ユーザのリピート分析でよく使うパターンで、マーケティング部門からのリクエストでも頻出します。

WHERE は集計前の行を絞り、HAVING は集計後のグループを絞る。同じ条件でもどちらに書くかで意味が変わるので、必ず使い分けを意識しましょう。

エイリアスは使えるか

HAVINGSELECT 句で定義した エイリアス が使えるかは DB 製品によって異なります。PostgreSQL や PGlite ではエイリアスがそのまま使えますが、移植性 を考えると エイリアスではなく集計式そのものを書く のが安全です。

SQL クエリ

-- 互換性重視 HAVING SUM(price) >= 10000 -- PG では動くが他 DB で動かない可能性 HAVING total_price >= 10000

よくある落とし穴

「集計関数の結果に対する条件は HAVING」と覚えるのが最短です。逆に集計関数を使わない単純な列の条件は WHERE で書く方が高速になりやすいです。性能と意味の両面から、WHERE 優先 → 必要なときだけ HAVING、が基本姿勢です。

もう一つの落とし穴は、HAVING に集計関数を使わない条件を書いてしまうケースです。HAVING price >= 1000 のような書き方は、GROUP BY に含まれない列を参照しているとエラーになります。集計関数か GROUP BY 列のみが HAVING の対象です。

実務でよく出る組み合わせパターン

HAVING は単体ではなく、WHERE / GROUP BY / ORDER BY と組み合わせて使う場面がほとんどです。たとえば「最近 30 日間 (WHERE で日付フィルタ) のユーザ別購入合計 (GROUP BY + SUM) が 10000 円以上 (HAVING) のユーザを、購入額の降順 (ORDER BY) で並べる」というクエリは、マーケティング部門が「優良顧客リスト」を作るときの典型形です。各句の役割を意識しながら組み合わせると、複雑な要件もきれいに分解できます。

まとめ

  • HAVING は GROUP BY の後ろに書き、集計後のグループに対するフィルタ
  • WHERE は集計前の行に対するフィルタ
  • 両者は併用可能、評価順は WHERE → GROUP BY → 集計 → HAVING
  • HAVING には集計関数や GROUP BY に指定した列を書く
  • 単純な列条件は WHERE で書くほうが高速
  • 優良顧客リストなど業務レポートの定番技

次のレッスン

次は SELECT文の実行順序 です。SQLのSELECT文がどのように実行されるのか、その順序について解説します。

事前確認 — 進む前に次の 3 つができることを確認しましょう。

  1. HAVING の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. HAVING とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン

テーブル構造

schema.sql

CREATE TABLE orders ( id INT PRIMARY KEY, user_id INT NOT NULL, product VARCHAR(50) NOT NULL, amount INT NOT NULL ); INSERT INTO orders (id, user_id, product, amount) VALUES (1, 101, 'ノートPC', 128000), (2, 101, 'キーボード', 6800), (3, 101, '小説A', 1800), (4, 102, 'マウス', 2980), (5, 102, 'コーヒー豆', 1500), (6, 102, '紅茶葉', 1200), (7, 103, 'マウス', 2980), (8, 104, '小説B', 2200);

期待される出力

user_idorder_count
1013
1023

ヒント

query.sql
query.sql
学習モード
コードの実行結果
データベースを初期化中...