青の統計学-DS Playground-

複数テーブルJOIN: 顧客・注文・商品をつなぐ

Stage 3 — 第5章 | データ分析基礎カリキュラム 推定学習時間:40〜50分 | 難易度:★★★☆☆


この章で学ぶこと

ここまで、2つのテーブルをJOINする方法を学びました。 実務の分析では、3つ以上のテーブルをつないで、ようやく知りたい情報がそろうことがあります。

ECサイトで「どの地域の顧客が、どの商品カテゴリを、どれくらい購入しているか」を見たい場合、顧客・注文・注文明細・商品をつなぐ必要があります。

この章を終えると、こんなことができるようになります:

  • 複数テーブルを順番にJOINできる
  • 顧客、注文、注文明細、商品を1つの結果につなげられる
  • JOINの順番と条件を読み解ける
  • 分析目的に合わせて必要な列だけを選べる

1. 分析したい問いから必要なテーブルを決める

複数テーブルJOINでは、いきなりSQLを書き始めるのではなく、まず問いを分解します。

たとえば、次の問いを考えます。

東京都の顧客が購入した商品のカテゴリ別売上を見たい

この問いに必要な情報は、複数のテーブルに分かれています。

必要な情報 テーブル 列の例
顧客の都道府県 customers customer_id, prefecture
注文の状態 orders order_id, customer_id, status
購入数量と単価 order_items order_id, product_id, quantity, unit_price
商品カテゴリ products product_id, category

このように、必要な列がどこにあるかを整理すると、JOINの道筋が見えてきます。


2. 顧客から注文へつなぐ

まず、顧客と注文を customer_id でつなぎます。

SELECT
            c.customer_id,
            c.customer_name,
            c.prefecture,
            o.order_id,
            o.order_date,
            o.status
          FROM customers AS c
          INNER JOIN orders AS o
            ON c.customer_id = o.customer_id;
          

この時点では、「誰がどの注文をしたか」が分かります。 ただし、まだ注文の中身である商品情報は分かりません。

複数テーブルJOINでは、1つずつ情報を足していくと理解しやすくなります。


3. 注文から注文明細へつなぐ

次に、注文と注文明細を order_id でつなぎます。

SELECT
            c.customer_id,
            c.prefecture,
            o.order_id,
            o.order_date,
            oi.product_id,
            oi.quantity,
            oi.unit_price
          FROM customers AS c
          INNER JOIN orders AS o
            ON c.customer_id = o.customer_id
          INNER JOIN order_items AS oi
            ON o.order_id = oi.order_id;
          

ここまでつなぐと、結果の1行は「注文明細1行」になります。 1つの注文に複数商品が含まれる場合、同じ order_id が複数行に出ます。

この粒度の変化を理解しておくことが、正しい集計につながります。


4. 注文明細から商品へつなぐ

最後に、注文明細と商品を product_id でつなぎます。

SELECT
            c.customer_id,
            c.prefecture,
            o.order_id,
            o.order_date,
            p.product_name,
            p.category,
            oi.quantity,
            oi.unit_price
          FROM customers AS c
          INNER JOIN orders AS o
            ON c.customer_id = o.customer_id
          INNER JOIN order_items AS oi
            ON o.order_id = oi.order_id
          INNER JOIN products AS p
            ON oi.product_id = p.product_id;
          

これで、顧客属性、注文情報、購入数量、商品カテゴリが1つの結果にそろいました。 この結果をもとに、商品カテゴリ別や地域別の分析ができるようになります。


5. カテゴリ別売上を集計する

複数テーブルをつないだら、分析目的に合わせて集計できます。 次のSQLは、東京都の顧客について、商品カテゴリ別の売上を集計します。

SELECT
            p.category,
            SUM(oi.quantity * oi.unit_price) AS sales_amount
          FROM customers AS c
          INNER JOIN orders AS o
            ON c.customer_id = o.customer_id
          INNER JOIN order_items AS oi
            ON o.order_id = oi.order_id
          INNER JOIN products AS p
            ON oi.product_id = p.product_id
          WHERE c.prefecture = '東京都'
            AND o.status = 'completed'
          GROUP BY p.category
          ORDER BY sales_amount DESC;
          

このSQLでは、売上を orders.total_amount ではなく、明細単位の quantity * unit_price で計算しています。 商品カテゴリ別に見るためには、明細単位で集計する必要があるためです。


6. 複数JOINを書くときの確認ポイント

複数テーブルJOINでは、SQLが長くなります。 長いSQLほど、途中で前提を確認することが大切です。

確認ポイント
どのテーブルを基準にするか 顧客基準か、注文基準か、明細基準か
JOIN条件は正しいか customer_id, order_id, product_id を取り違えていないか
結果の1行は何を表すか 顧客、注文、明細のどれか
集計列は粒度に合っているか カテゴリ別なら明細金額を使う
除外条件は明確か キャンセル注文を含めるか除くか

最初から完成形を書くのではなく、2テーブルずつJOINして結果を確認しながら進めると、ミスに気づきやすくなります。


7. 分析にJOINが必要な理由

JOINは、単にテーブルを横につなげる構文ではありません。 分析したい問いに必要な情報を、正しい粒度でそろえるための操作です。

たとえば、次のような問いはJOINなしでは答えにくいです。

  • 地域別に人気の商品カテゴリを見たい
  • 未購入顧客と購入済み顧客を比較したい
  • 商品カテゴリ別の売上を注文日ごとに見たい
  • 顧客ごとの購入商品数を集計したい

実務では、データは整理のために分かれて保存され、分析では目的に合わせてつなぎ直します。 JOINは、その橋渡しをする基本スキルです。


実務での使いどころ: 問いから必要なテーブルを逆算する

複数テーブルJOINでは、先にJOINを書くのではなく、分析したい問いから必要な情報を逆算します。 たとえば「カテゴリ別売上」を見たいなら、売上金額、商品カテゴリ、注文状態が必要です。

必要な情報 ありそうなテーブル
注文状態 orders
商品ごとの数量と単価 order_items
商品カテゴリ products

このように分解すると、必要なJOIN経路が見えてきます。

SELECT
            p.category,
            SUM(oi.quantity * oi.unit_price) AS sales
          FROM orders AS o
          JOIN order_items AS oi
            ON o.order_id = oi.order_id
          JOIN products AS p
            ON oi.product_id = p.product_id
          WHERE o.status = 'completed'
          GROUP BY p.category
          ORDER BY sales DESC;
          

複数JOINでは、1つのJOINミスが全体の結果に影響します。 JOINを1つ追加するたびに、行数とサンプルを確認しましょう。

ミニ演習

次の分析に必要なテーブルを考えてください。

  1. 都道府県別の売上を見たい。
  2. 商品カテゴリ別の購入者数を見たい。
  3. 顧客ごとの購入商品数を見たい。
  4. 複数JOINで行数確認が重要な理由を説明する。

まとめ

つなぐ関係 JOIN条件 追加できる情報
顧客と注文 c.customer_id = o.customer_id 誰が注文したか
注文と注文明細 o.order_id = oi.order_id 何個買ったか
注文明細と商品 oi.product_id = p.product_id 商品名・カテゴリ

この章のキーメッセージ: 複数テーブルJOINでは、分析したい問いから必要なテーブルを逆算します。JOIN条件、結果の粒度、集計列の意味を確認しながら、段階的にSQLを組み立てましょう。


この章の確認

  1. 「地域別の商品カテゴリ売上」を見るために必要な4つのテーブルを挙げてください。
  2. ordersorder_items は、どの列でJOINしますか?
  3. 商品カテゴリ別売上を集計するとき、なぜ orders.total_amount ではなく quantity * unit_price を使うことがありますか?
  4. 複数テーブルJOINを書く前に、分析したい問いを分解する理由を説明してください。

関連演習