SQL入門 STEP12|INNER JOINでテーブルを結合しよう

karin@taishi@felmia

2つのテーブルからデータを取得したい

STEP11では、商品とカテゴリーを別々のテーブルに分けました。

現在のproductsテーブルは次のようになっています。

product_id | product_name    | price  | category_id
-----------+-----------------+--------+------------
1          | ノートPC         | 120000 | 1
2          | マウス           | 3000   | 2
3          | キーボード        | 8000   | 2
4          | モニター          | 30000  | 2
5          | USBメモリ        | 2000   | 3
6          | Webカメラ        | 7000   | 2
7          | ヘッドセット      | 7000   | 2
8          | HDMIケーブル 2m   | 1800   | 3

そしてcategoriesテーブルには、カテゴリーの情報があります。

category_id | category_name
------------+---------------
1           | PC
2           | 周辺機器
3           | アクセサリ

例えば、マウスを見るとcategory_idは2です。

categoriesでID2を見ると、

2 | 周辺機器

となっています。

そのため、マウスのカテゴリーは「周辺機器」だと分かります。

ただ、毎回2つのテーブルを別々にSELECTして確認するのは面倒ですよね。

できれば、

product_name | price  | category_name
-------------+--------+---------------
ノートPC      | 120000 | PC
マウス        | 3000   | 周辺機器
キーボード     | 8000   | 周辺機器

のように、商品とカテゴリーを一緒に表示したいところです。

そこで使うのがJOIN(結合)です。

JOINとは?

JOINは、複数のテーブルを関連付けてデータを取得するときに使います。

今回の2つのテーブルには、共通してcategory_idがあります。

products                           categories

product_name | category_id        category_id | category_name
-------------+------------        ------------+--------------
ノートPC      | 1           ←→     1           | PC
マウス        | 2           ←→     2           | 周辺機器
USBメモリ     | 3           ←→     3           | アクセサリ

このcategory_idを手がかりにして、商品とカテゴリーを結び付けます。

JOINとは?

複数のテーブルを関連付けて、必要なデータをまとめて取得するときに使います。

今回なら、

products.category_id
        ↓
categories.category_id

を使って2つのテーブルを結合します。

STEP11で主キーと外部キーを学んだ理由が、ここでつながってきます。

INNER JOINを使ってみよう

まずは実際にSQLを動かしてみましょう。

Query Toolで次のSQLを実行してください。

SELECT
    products.product_name,
    products.price,
    categories.category_name
FROM products
INNER JOIN categories
    ON products.category_id = categories.category_id;

少し長くなりました。

ですが、実行結果を見ると何をしているのか分かりやすくなります。

product_name     | price  | category_name
-----------------+--------+---------------
ノートPC          | 120000 | PC
マウス            | 3000   | 周辺機器
キーボード         | 8000   | 周辺機器
モニター           | 30000  | 周辺機器
USBメモリ         | 2000   | アクセサリ
Webカメラ         | 7000   | 周辺機器
ヘッドセット       | 7000   | 周辺機器
HDMIケーブル 2m   | 1800   | アクセサリ

productsにはなかったcategory_nameを、商品名や価格と一緒に取得できました。

ルミィ
ルミィ

商品テーブルとカテゴリーテーブルが、1つの表みたいに表示されたね♪

INNER JOINを分けて見てみよう

先ほどのSQLを一気に覚える必要はありません。

順番に見ていきます。

まずはSELECTです。

SELECT
    products.product_name,
    products.price,
    categories.category_name

ここでは、取得したいカラムを指定しています。

少し違うのは、

products.product_name
categories.category_name

のように、カラム名の前にテーブル名が付いていることです。

書き方は、

テーブル名.カラム名

です。

.を使って、

「どのテーブルにあるカラムなのか」

を指定しています。

FROMで基準になるテーブルを指定する

続いて、

FROM products

です。

今回は商品を一覧として取得したいので、productsをFROMに指定しています。

そのproductsへ、

INNER JOIN categories

としてcategoriesを結合しています。

ここまでを日本語にすると、

「productsを基準にして、categoriesを結合する」

くらいに考えておけば大丈夫です。

ONで「どことどこをつなぐか」を指定する

JOINで特に大切なのがONです。

今回のSQLでは、

ON products.category_id = categories.category_id

と書いています。

これは、

productsのcategory_idとcategoriesのcategory_idが同じデータを結び付ける

という意味です。

例えばマウスなら、

products
マウス | category_id = 2

              ↓ 2 = 2

       categories
       2 | 周辺機器

となります。

2と2が一致しているため、この2つのデータが結び付きます。

その結果、

マウス | 3000 | 周辺機器

として取得できます。

JOINではONを見る

SQLが長く感じたら、まずONを見てみましょう。

ON products.category_id = categories.category_id

ここを見ると、

「productsのcategory_idとcategoriesのcategory_idを使って結合している」

ことが分かります。

INNER JOINの基本形

今回使ったSQLを一般的な形にすると、次のようになります。

SELECT カラム名
FROM テーブルA
INNER JOIN テーブルB
    ON テーブルA.カラム = テーブルB.カラム;

今回なら、

FROM products
INNER JOIN categories
    ON products.category_id = categories.category_id

です。

最初は構文を丸ごと暗記しようとするより、

FROM → どのテーブルから見る?

INNER JOIN → どのテーブルをつなぐ?

ON → 何を使ってつなぐ?

と分けて考えたほうが理解しやすいです。

INNER JOINは一致したデータを取得する

ここでINNER JOINの「INNER」が何を意味しているのか確認しておきます。

INNER JOINでは、ONの条件に一致したデータが結果に表示されます。

現在の商品はすべて、

category_id = 1
category_id = 2
category_id = 3

のどれかを持っています。

そしてcategoriesにも、

1 | PC
2 | 周辺機器
3 | アクセサリ

があります。

そのため、現在はすべての商品がINNER JOINの結果に表示されます。

INNER JOIN

ONで指定した条件が一致するデータを結合して取得します。

今回なら、

products.category_id = categories.category_id

が一致する商品とカテゴリーが結果に表示されます。

では、一致するカテゴリーがない商品があったらどうなるのか。

これは次のSTEP13でLEFT JOINと比較しながら確認します。

テーブル名を付ける理由

ここまで、

products.product_name
categories.category_name

のように書いてきました。

「product_nameだけじゃダメなの?」

と思ったかもしれません。

今回のproduct_nameはproductsにしかないので、状況によってはカラム名だけでも取得できます。

ただし、category_idはどうでしょう。

productsにも、

products.category_id

があります。

categoriesにも、

categories.category_id

があります。

単に、

category_id

と書いただけでは、どちらのcategory_idなのか分かりません。

JOINでは複数のテーブルを扱うので、

テーブル名.カラム名

と書く場面が増えてきます。

ASを使ってテーブル名を短くしよう

products.product_nameのような書き方は分かりやすい反面、何度も書くとSQLが長くなります。

そこで、STEP9でも登場したASを使って、テーブルにも別名を付けてみましょう。

SELECT
    p.product_name,
    p.price,
    c.category_name
FROM products AS p
INNER JOIN categories AS c
    ON p.category_id = c.category_id;

かなり短くなりました。

ここでは、

products AS p

で、

categoriesをcという名前で扱う

ようにしています。

そのため、

products.product_name

の代わりに、

p.product_name

と書けます。

ルミィ
ルミィ

pはproducts、cはcategoriesの短い名前なんだね!

別名は分かりやすいものを使おう

テーブルの別名は自由に付けられます。

例えば、

FROM products AS x
INNER JOIN categories AS z

としてもSQLとしては使えます。

ですが、xやzでは何のテーブルなのか分かりにくいですよね。

今回のように、

products   → p
categories → c

とすると、元のテーブルを想像しやすくなります。

短くすれば何でもよいのではなく、後から読んだときに分かる名前にすることも意識しておきましょう。

WHEREと組み合わせてみよう

INNER JOINした結果に、WHEREで条件を付けることもできます。

例えば、

「周辺機器だけを取得したい」

場合は次のように書けます。

SELECT
    p.product_name,
    p.price,
    c.category_name
FROM products AS p
INNER JOIN categories AS c
    ON p.category_id = c.category_id
WHERE c.category_name = '周辺機器';

INNER JOINで商品とカテゴリーを結合したあと、WHEREで周辺機器に絞っています。

これまで使ってきたWHEREが、JOINでもそのまま使えます。

ORDER BYも組み合わせてみよう

価格の高い商品から並べたいなら、ORDER BYも追加できます。

SELECT
    p.product_name,
    p.price,
    c.category_name
FROM products AS p
INNER JOIN categories AS c
    ON p.category_id = c.category_id
ORDER BY p.price DESC;

SQLがだいぶ長くなりました。

ただ、新しく登場したのはINNER JOINとONです。

SELECTもORDER BYも、すでに使ったことがあります。

長いSQLを見たときに全部を新しいものとして考えるのではなく、

SELECT       → 何を取得する?
FROM         → どこから?
INNER JOIN   → 何を結合する?
ON           → 何を使って結合する?
WHERE        → どのデータに絞る?
ORDER BY     → どう並べる?

と分けて見てみると、ずっと読みやすくなります。

JOINした結果から必要なカラムだけを取得できる

JOINすると、2つのテーブルのカラムを全部表示しなければいけないわけではありません。

例えば、商品名とカテゴリー名だけ欲しいなら、

SELECT
    p.product_name,
    c.category_name
FROM products AS p
INNER JOIN categories AS c
    ON p.category_id = c.category_id;

で十分です。

価格が必要なければ、SELECTにp.priceを書かなければよいだけです。

これはSTEP3で学んだ、

「必要なカラムだけSELECTする」

という考え方と同じです。

結合するカラムを間違えるとどうなる?

JOINではONの条件がとても重要です。

例えば、

ON p.product_id = c.category_id

と書いてしまったとします。

どちらも整数なので、一部の値が偶然一致する可能性があります。

ですが、

product_idは商品を特定するID。

category_idはカテゴリーを特定するID。

役割が違います。

今回つなぎたいのは、

products.category_id
        ↓
categories.category_id

です。

同じデータ型だから結合するわけではない

JOINでは、

「どのカラムとどのカラムに関係があるのか」

を考えてONを書きます。

今回なら、STEP11で作った主キーと外部キーの関係を使います。

JOINがうまくいかないときは、SQLの書き方だけでなく、結合するカラムが本当に合っているかも確認してみましょう。

よくある間違い

ONに違うカラムを書いている

今回の正しい関係は、

ON p.category_id = c.category_id

です。

名前が似ているからではなく、商品が持つカテゴリーIDと、カテゴリーを特定するIDをつないでいます。

どちらのテーブルのカラムか分からなくなる

JOINでは複数のテーブルを扱います。

p.product_name
p.price
c.category_name

のように、テーブル名や別名を付けると分かりやすくなります。

INNER JOINだけを丸暗記しようとする

次のSQLを一行の呪文として覚える必要はありません。

FROM products AS p
INNER JOIN categories AS c
    ON p.category_id = c.category_id

productsから見て、

categoriesを、

category_idが一致するところでつなぐ。

まずはこの意味を理解しておきましょう。

STEP12のまとめ

STEP12のポイント

  • JOINを使うと複数のテーブルを関連付けてデータを取得できる
  • INNER JOINはONの条件に一致するデータを結合する
  • ONで結合するカラムを指定する
  • テーブル名.カラム名で、どのテーブルのカラムなのか指定できる
  • ASを使ってテーブルに短い別名を付けられる
  • JOINした結果にもWHEREやORDER BYを使える
  • JOINでは、どのカラム同士に関係があるのかを考えることが大切

INNER JOINは、ここまでのSQLより少し長く見えます。

ですが、やっていることは、

「商品が持っているcategory_idと、カテゴリー側のcategory_idを照らし合わせる」

というものです。

SQLの形だけを見るより、まず2つのテーブルの関係を確認してからJOINを書くほうが理解しやすくなります。

今回の例なら、

products.category_id
        ↓
categories.category_id

この関係が分かっていれば、ONに何を書くのかも見えてきます。

ルミィ
ルミィ

STEP12クリア!
別々だった商品とカテゴリーを、1回のSELECTで一緒に見られるようになったね♪

次のSTEPへ

今回使ったINNER JOINでは、結合条件に一致するデータを取得しました。

では、

「商品は残したいけれど、まだカテゴリーが決まっていない」

というデータがあったらどうなるでしょう。

INNER JOINでは、結合相手が見つからないデータは結果に出てきません。

次はLEFT JOINを使って、INNER JOINとの違いを実際のデータで比べてみます。

→ STEP13「LEFT JOINを使ってみよう」

学習内容を確認したいときは、SQL入門の一覧から各STEPを確認できます。

→ SQL入門|初心者が基礎から学べるSQL学習ガイド

記事URLをコピーしました