SQL入門 STEP12|INNER JOINでテーブルを結合しよう
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_idproductsから見て、
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との違いを実際のデータで比べてみます。
学習内容を確認したいときは、SQL入門の一覧から各STEPを確認できます。
