本文へスキップ
BecomeCoder

SQL データ操作 (DML)コース · 第2章 集計する · レッスン8

HAVING と実行順序 ― 集計結果で絞り込む

ブラウザで完結

導入

「商品が2つ以上あるカテゴリだけ見たい」――これは集計した結果に対する絞り込みです。ここで WHERE を使おうとすると、うまくいきません。集計の前と後では、絞り込みに使う道具が違うのです。この違いが分かると、SQL の各句が「どんな順で実行されるか」まで見通せるようになります。

説明

WHERE は「集計するの、1行1行」を絞り込みます。一方、HAVING は「集計したのグループ」を絞り込みます。

flowchart LR
    F["FROM<br/>表を読む"] --> W["WHERE<br/>行を絞る(集計前)"]
    W --> G["GROUP BY<br/>グループに分ける"]
    G --> H["HAVING<br/>グループを絞る(集計後)"]
    H --> S["SELECT<br/>列・集計を選ぶ"]
    S --> O["ORDER BY<br/>並べ替える"]

この「FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY」という実行順序が、SQL 集計の背骨です。書く順番(SELECT が先頭)と、実際に処理される順番(FROM が先)が違う点に注目してください。

「商品が2つ以上あるカテゴリ」はこう書きます。

SELECT category_id, COUNT(*) AS 商品数
FROM products
GROUP BY category_id
HAVING COUNT(*) >= 2;

WHEREHAVING は併用できます。順序どおり、「まず WHERE で行を絞ってから集計し、HAVING でグループを絞る」と流れます。たとえば「価格1000円以上の商品だけを対象に、平均価格が5000円を超えるカテゴリ」はこうです。

SELECT category_id, AVG(price) AS 平均
FROM products
WHERE price >= 1000
GROUP BY category_id
HAVING AVG(price) > 5000;

やってみよう

初期表示のクエリを実行し、商品が2つ以上あるカテゴリだけが残ることを確認しましょう。次に HAVING COUNT(*) >= 2WHERE COUNT(*) >= 2 に書き換えて実行し、エラーになることを見てください。「集計結果の絞り込みは HAVING」――これを体で覚えられます。

演習

ordersuser_id ごとにまとめ、注文が2件以上ある会員の user_id と注文件数だけを取り出してください。

ヒント1を見る

グループ分けのあと、HAVING COUNT(*) >= 2 で集計結果を絞ります。

ヒント2を見る

SELECT user_id, COUNT(*) AS 件数 FROM orders GROUP BY user_id HAVING COUNT(*) >= 2;

実際に動かしてみよう

下のエディタにクエリを書いて「実行」を押すと、ブラウザ内のSQLiteで結果が表示されます。本文の例をそのまま試したり、書き換えたりしてみましょう。

SQL — ブラウザ内で実行(SQLite)

ブラウザ内でSQLを動かす環境(SQLite)を読み込みます(初回のみ一瞬)。
スクロールして表示された時点でも自動で読み込まれます。