導入
前レッスンの集計は「全体でまとめて1つ」でした。でも本当に知りたいのは、「カテゴリごとの商品数」「会員ごとの注文数」のように、グループに分けた集計であることがほとんどです。これを行うのが GROUP BY です。
説明
GROUP BY 列 は「その列が同じ値の行を1グループにまとめ、グループごとに集計関数を計算する」という指定です。
flowchart LR
T["products(全7行)"]
T -->|"GROUP BY category_id<br/>同じカテゴリでまとめる"| G1["category 1<br/>キーボード・マウス・スピーカー・Webカメラ"]
T --> G2["category 2<br/>モニター"]
T --> G3["category 3<br/>ノートPC"]
T --> G4["category 4<br/>USBケーブル"]
G1 -->|"COUNT/AVG"| R["カテゴリごとに<br/>1行ずつの集計結果"]
G2 --> R
G3 --> R
G4 --> R
SELECT category_id, COUNT(*) AS 商品数, AVG(price) AS 平均価格
FROM products
GROUP BY category_id;
GROUP BY を使うときの鉄則がひとつあります。SELECT に並べてよいのは「グループ分けに使った列」か「集計関数」だけです。たとえば GROUP BY category_id したうえで SELECT name を書くと、「1グループに商品名は複数あるのに、どれを出せばいいの?」と辻褄が合わなくなります。「グループの代表になる列」か「まとめた計算結果」だけを選ぶ、と覚えてください。
やってみよう
初期表示のクエリを実行し、カテゴリごとに商品数と平均価格が並ぶことを確認しましょう。次に orders を GROUP BY user_id でまとめ、SELECT user_id, COUNT(*) AS 注文数 FROM orders GROUP BY user_id; を実行して、会員ごとの注文数を見てみてください。
演習
orders テーブルを状態(status)ごとにまとめ、status と、その状態の注文件数を取り出してください。
ヒント1を見る
グループ分けは GROUP BY status、件数は COUNT(*) です。
ヒント2を見る
SELECT status, COUNT(*) AS 件数 FROM orders GROUP BY status;