結合の実践演習

結合の実践演習 とは

複数のテーブルを結合する実践的な演習です。JOIN句を使いこなしましょう。本レッスンでは、結合の実践演習 の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。

なぜ重要か

ここまで学んだ INNER JOIN / OUTER JOIN / SELF JOIN / 集合演算を組み合わせ、実務でよくある「売上分析レポート」を作る練習をします。1 つのクエリで複数の結合・集計・並び替えをこなすパターンは、現場のレビューでよく出題されるシナリオです。型に慣れておくと、どんなデータベースを触っても応用が効きます。実際のレポート業務では「結合 + 集計 + 並び替え + ゼロ表示」がワンセットで求められることがほとんどで、このレッスンの 1 本を書き切れるかが SQL の中級ラインの目安と言えます。

実践シナリオ — 商品ごとの売上集計

3 テーブルが用意されています。products (商品マスタ)、orders (注文ヘッダ)、order_items (注文明細) です。これを使って商品ごとに次の情報を出すレポートを作ります。

  • 商品名
  • 注文された個数の合計
  • 売上 (price × quantity の合計)
  • 注文が 1 件もない商品も「0 個・0 円」で残す

設計のステップ

diagram (will load when visible)

左に products を置き、order_itemsLEFT JOIN するのがポイントです。INNER JOIN にすると未販売商品が消えてしまいます。「主軸を左に、関連を右に」がレポート系 SQL の基本姿勢です。

ステップ 1 — 結合だけ書いてみる

SQL クエリ

SELECT p.id, p.name, oi.quantity, p.price FROM products p LEFT JOIN order_items oi ON p.id = oi.product_id;

まずは結合だけを書いて、未販売商品が NULL で残ることを確認します。期待通り NULL が混じったら、次は集計を足していきます。

ステップ 2 — 集計をかける

SQL クエリ

SELECT p.id, p.name, COALESCE(SUM(oi.quantity), 0) AS qty, COALESCE(SUM(oi.quantity * p.price), 0) AS revenue FROM products p LEFT JOIN order_items oi ON p.id = oi.product_id GROUP BY p.id, p.name ORDER BY revenue DESC, p.id;

GROUP BYSUM を加えれば商品ごとの集計レポートが完成します。COALESCE(SUM, 0) で未販売商品は 0 に丸めます。

落とし穴

LEFT JOIN + GROUP BY で集計するときは、SUM の結果が NULL になり得ることを忘れがちです。COALESCE(SUM(...), 0) で 0 に変換すれば、レポート上で「未販売 = 空白」ではなく「未販売 = 0」と明示できます。経営層に出すレポートでは「空白」より「0」のほうが意図が伝わりやすいので、この一手を入れる癖をつけておきましょう。

GROUP BY に書く列は SELECT 句の非集計列とすべて一致させてください。Postgres / 標準 SQL では p.id, p.name の両方を GROUP BY に書く必要があります。MySQL の緩いモード (ONLY_FULL_GROUP_BY 無効) に慣れていると忘れがちなので注意。本番環境でモードが変わったときに動かなくなるパターンの典型です。

演習で扱う 3 テーブル

SQL クエリ

products (id, name, price) orders (id, order_date) order_items (id, order_id, product_id, quantity)

商品マスタは 5 件、注文は 3 件、明細は 4 件用意してあります。商品の中には注文 0 件のものも含まれているので、LEFT JOIN を忘れないようにしてください。

発展課題のヒント

もし余裕があれば、orders.order_date を JOIN に追加して「今月だけの売上」を出してみると、さらに実務に近い練習になります。o.order_date >= '2026-05-01' のような条件を ON 句または WHERE 句のどちらに書くかで結果が変わるので、両方試してみると LEFT JOIN の挙動への理解が深まります。

チェックリスト

この演習を完成させる前に、次のチェックリストを確認してみてください。

  • 出力列名が product_id, product_name, total_quantity, total_revenue になっているか
  • 未販売商品 (ヘッドセット、ウェブカメラ) が結果に残っているか
  • total_revenue が降順、同点なら product_id 昇順で並んでいるか
  • COALESCE で NULL を 0 に変換しているか
  • GROUP BY に p.idp.name の両方が含まれているか

この 5 つを満たせば合格です。実務でこの形を書けることは、SQL 中級の重要な指標になります。

まとめ

  • 主軸テーブルを左に置き、LEFT JOIN で広げる
  • 未集計の NULLCOALESCE で 0 に丸める
  • GROUP BY は SELECT 句の非集計列をすべて含める
  • 並び順は ORDER BY revenue DESC, id ASC のように複数指定が可能
  • 条件を ONWHERE のどちらに書くかで OUTER JOIN の効果が変わる
  • チェックリストで自分のクエリを最終確認する習慣を付ける

次のレッスン

次は テーブル結合クイズ です。テーブル結合の理解度をクイズで確認!複数のテーブルからデータを抽出する力を試しましょう。

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

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

理解度チェック (30 秒)

Q. 結合 実践 とは何か、1 文で説明してください。

この章のポイント

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

関連レッスン

テーブル構造

schema.sql

CREATE TABLE products ( id INT PRIMARY KEY, name VARCHAR(50), price INT ); CREATE TABLE orders ( id INT PRIMARY KEY, order_date DATE ); CREATE TABLE order_items ( id INT PRIMARY KEY, order_id INT, product_id INT, quantity INT ); INSERT INTO products VALUES (1, 'マウス', 2500), (2, 'キーボード', 8000), (3, 'モニター', 35000), (4, 'ヘッドセット', 6000), (5, 'ウェブカメラ', 4500); INSERT INTO orders VALUES (1001, '2026-05-01'), (1002, '2026-05-03'), (1003, '2026-05-10'); INSERT INTO order_items VALUES (1, 1001, 1, 3), (2, 1001, 2, 1), (3, 1002, 3, 1), (4, 1003, 1, 2);

期待される出力

product_idproduct_nametotal_quantitytotal_revenue
3モニター135000
1マウス512500
2キーボード18000
4ヘッドセット00
5ウェブカメラ00

ヒント

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