INNER JOIN: 一致する行だけをつなぐ
Stage 3 — 第2章 | データ分析基礎カリキュラム 推定学習時間:30〜40分 | 難易度:★★☆☆☆
この章で学ぶこと
前章では、テーブル同士をつなぐために主キーと外部キーを見ることを学びました。 この章では、JOINの中でも最も基本的な INNER JOIN を扱います。
INNER JOINは、指定した条件に一致する行だけをつなぎます。 EC分析では「注文した顧客の情報を付ける」「購入された商品のカテゴリを付ける」といった場面でよく使います。
この章を終えると、こんなことができるようになります:
- INNER JOINの基本形を書ける
ONでテーブル同士の対応条件を指定できる- 一致しない行が結果から除かれることを説明できる
- 顧客情報と注文情報を組み合わせた分析SQLを書ける
1. INNER JOINは「両方にあるものだけ」を残す
INNER JOINは、2つのテーブルを指定した条件でつなぎ、条件に一致した行だけを結果に残します。
たとえば、customers と orders を customer_id でつなぐとします。
| customers | orders |
|---|---|
| 顧客の名前や都道府県 | 注文日や注文金額 |
このJOINによって、「どの顧客が、いつ、いくら注文したか」を1つの結果として見られるようになります。
ただし、INNER JOINでは注文がない顧客は結果に出ません。
orders 側に一致する行がないためです。
2. INNER JOINの基本形
INNER JOINの基本形は次の通りです。
SELECT
列名
FROM テーブルA
INNER JOIN テーブルB
ON テーブルA.列名 = テーブルB.列名;
顧客と注文をつなぐSQLは、次のようになります。
SELECT
customers.customer_id,
customers.customer_name,
customers.prefecture,
orders.order_id,
orders.order_date,
orders.total_amount
FROM customers
INNER JOIN orders
ON customers.customer_id = orders.customer_id;
ON の後には、どの列同士を対応させるかを書きます。
この例では、customers.customer_id と orders.customer_id が同じ行だけをつなぎます。
3. テーブル名を列名につける理由
JOINすると、複数のテーブルに同じ列名が出てくることがあります。
たとえば customer_id は customers にも orders にもあります。
そのため、JOINでは次のように テーブル名.列名 で書くと安全です。
SELECT
customers.customer_id,
orders.customer_id,
orders.order_id
FROM customers
INNER JOIN orders
ON customers.customer_id = orders.customer_id;
実際の分析では、同じ意味のIDを両方表示する必要は少ないため、片方だけを出すことが多いです。
SELECT
customers.customer_id,
customers.customer_name,
orders.order_id,
orders.total_amount
FROM customers
INNER JOIN orders
ON customers.customer_id = orders.customer_id;
列名の衝突を避けるために、JOINでは列の出どころを意識しましょう。
4. 別名を使って読みやすくする
テーブル名が長くなると、SQLが読みにくくなります。 その場合は、テーブルに別名をつけます。
SELECT
c.customer_id,
c.customer_name,
c.prefecture,
o.order_id,
o.order_date,
o.total_amount
FROM customers AS c
INNER JOIN orders AS o
ON c.customer_id = o.customer_id;
ここでは、customers を c、orders を o と呼んでいます。
別名を使うと、JOINするテーブルが増えたときもSQLを読みやすく保てます。
ただし、初学者のうちは別名が何を指しているか分からなくなりやすいです。
c は customers、o は orders のように、意味が推測しやすい短い名前を使いましょう。
5. INNER JOINで分析できること
INNER JOINを使うと、注文テーブルだけでは見えなかった顧客属性を使えるようになります。
たとえば、完了した注文について顧客の都道府県も一緒に見たい場合は、次のように書きます。
SELECT
o.order_id,
o.order_date,
c.customer_name,
c.prefecture,
o.total_amount
FROM orders AS o
INNER JOIN customers AS c
ON o.customer_id = c.customer_id
WHERE o.status = 'completed';
この結果を使えば、次のような問いに進めます。
- どの都道府県の顧客が多く注文しているか
- 高額注文はどの地域に多いか
- 新規顧客と既存顧客で注文傾向が違うか
JOINは、分析に必要な列を1つの結果に集めるための準備です。
6. INNER JOINで消える行に注意する
INNER JOINでは、一致する相手がない行は結果から除かれます。 たとえば次のような行は、顧客と注文のINNER JOINには出ません。
| 行 | 出ない理由 |
|---|---|
| 注文がない顧客 | orders に一致する customer_id がない |
| 顧客IDが不明な注文 | customers に一致する customer_id がない |
これは便利な性質でもあります。 「実際に注文した顧客だけを見たい」なら、INNER JOINは自然な選択です。
一方で、「未購入の顧客も含めて見たい」場合は、INNER JOINでは不十分です。 その場合は次章で学ぶLEFT JOINを使います。
実務での使いどころ: 両方に存在するデータだけを見る
INNER JOINは、両方のテーブルに対応する行があるものだけを残します。 たとえば「注文がある顧客だけ」を見たい場合には自然ですが、「まだ注文していない顧客」も分析したい場合には不向きです。
SELECT
c.customer_id,
c.customer_name,
o.order_id,
o.total_amount
FROM customers AS c
INNER JOIN orders AS o
ON c.customer_id = o.customer_id;
このSQLでは、注文がない顧客は結果に出ません。 これはミスではなく、INNER JOINの性質です。
| 見たいもの | INNER JOINが向くか |
|---|---|
| 購入済み顧客の注文 | 向いている |
| 未購入顧客も含む顧客一覧 | 向いていない |
| 商品がある注文明細 | 向いている |
| 商品マスタに未登録の明細を探す | 向いていないことがある |
INNER JOINを使うときは、「対応先がない行を落としてよいか」を確認しましょう。
ミニ演習
次の分析でINNER JOINを使ってよいか考えてください。
- 購入済み顧客の注文金額を見たい。
- 登録顧客全員について、購入有無を見たい。
- 注文明細に商品名を付けたい。
- INNER JOINで未購入顧客が消える理由を説明する。
まとめ
| 構文 | 意味 | 例 |
|---|---|---|
INNER JOIN |
一致する行だけをつなぐ | INNER JOIN orders |
ON |
JOIN条件を指定する | ON c.customer_id = o.customer_id |
テーブル名.列名 |
列の出どころを明確にする | orders.total_amount |
| テーブル別名 | SQLを短く読みやすくする | customers AS c |
この章のキーメッセージ: INNER JOINは、両方のテーブルで対応する行だけを残します。購入済みデータの分析には便利ですが、一致しない行が消えることを必ず意識しましょう。
この章の確認
- INNER JOINでは、一致する相手がない行はどうなりますか?
customersとordersをつなぐとき、どの列同士をONで指定しますか?- JOINしたSQLで
テーブル名.列名と書く理由を説明してください。 - 注文がある顧客だけを見たい場合、INNER JOINが向いている理由を説明してください。