今回やること
この記事では、注文データを使って、COUNT、SUM、AVG、GROUP BY、HAVING を練習します。
集計SQLは、1行ずつ見るのではなく、グループごとの結果を見るSQLです。
前提条件
SELECTとWHEREの基本を知っている- 学習用データベースで試す
- 金額は整数として扱う
Step 1: 注文テーブルを作る
CREATE TABLE orders (
id INTEGER PRIMARY KEY,
user_id INTEGER NOT NULL,
status TEXT NOT NULL,
total INTEGER NOT NULL,
ordered_at DATE NOT NULL
);
Step 2: データを入れる
INSERT INTO orders (id, user_id, status, total, ordered_at) VALUES
(1, 1, 'paid', 3000, '2026-01-10'),
(2, 1, 'paid', 1500, '2026-01-15'),
(3, 2, 'pending', 5000, '2026-02-01'),
(4, 2, 'paid', 8000, '2026-02-10'),
(5, 3, 'paid', 1200, '2026-03-05'),
(6, 3, 'cancelled', 2000, '2026-03-08');
Step 3: 全体の件数を数える
SELECT COUNT(*) AS order_count
FROM orders;
COUNT(*) は行数を数えます。
Step 4: 合計と平均を出す
SELECT
SUM(total) AS total_sales,
AVG(total) AS average_order_total
FROM orders;
このSQLでは、全注文の合計金額と平均金額を出します。
Step 5: WHEREで集計対象を絞る
支払い済みの注文だけを集計します。
SELECT
COUNT(*) AS paid_order_count,
SUM(total) AS paid_total_sales
FROM orders
WHERE status = 'paid';
WHEREは集計する前に、対象行を絞るために使います。
Step 6: GROUP BYでユーザーごとに集計する
SELECT
user_id,
COUNT(*) AS order_count,
SUM(total) AS total_sales
FROM orders
GROUP BY user_id;
user_id ごとに注文数と合計金額を出します。
Step 7: HAVINGで集計後に絞る
注文数が2件以上のユーザーだけを取得します。
SELECT
user_id,
COUNT(*) AS order_count
FROM orders
GROUP BY user_id
HAVING COUNT(*) >= 2;
COUNT(*) >= 2 は集計後にしか判断できないため、HAVING に書きます。
Step 8: 並び替える
合計金額が大きい順に並べます。
SELECT
user_id,
SUM(total) AS total_sales
FROM orders
WHERE status = 'paid'
GROUP BY user_id
ORDER BY total_sales DESC;
ORDER BY では、SELECT で付けた別名を使えることがあります。
よくあるエラー
| エラー | よくある原因 | 確認すること |
|---|---|---|
| 集計条件をWHEREに書いている | WHERE COUNT(*) >= 2 としている | 集計後条件は HAVING |
| グループ化していない列をSELECTしている | status などをそのまま出している | GROUP BY に含めるか集計する |
| 件数が想定と違う | WHERE の条件が違う | 集計前の行をSELECTで確認 |
| 平均が想定と違う | キャンセルも含めている | WHERE status = 'paid' を確認 |
まとめ
COUNT は件数、SUM は合計、AVG は平均を出します。GROUP BY を使うと、ユーザーごと、ステータスごとなどに分けて集計できます。WHERE は集計前、HAVING は集計後の条件です。