JOINの種類と使い分け — テーブルを結合する

SQLのJOINで複数のテーブルを結合する方法を解説します。INNER JOINとLEFT JOINの違い、結合条件の書き方、3テーブル以上の結合まで基礎からまとめます。

リレーショナルデータベースでは、データを複数のテーブルに分けて持つのが普通です。たとえば「顧客」と「注文」は別々のテーブルにし、注文側に「どの顧客の注文か」を表す列を持たせます。こうして分かれたテーブルを、共通のキーでつなぎ合わせて1つの結果にするのが JOIN です。

なぜテーブルを分けるのか

1つの大きな表にすべてを詰め込むと、同じ情報が何度も繰り返され、更新漏れや矛盾が起きやすくなります。そこで、意味のまとまりごとにテーブルを分け、外部キーでつなぎます。

たとえば次の2つのテーブルを考えます。

customers(顧客)

idnamecity
1AliceTokyo
2BobOsaka
3DaveTokyo

orders(注文)

idcustomer_idamount
11500
21300
32800

orders.customer_idcustomers.id を指しています。この対応関係を使って、「注文と、その注文をした顧客の名前」を一緒に取り出すのが結合です。

INNER JOIN — 両方に一致する行

もっとも基本的な結合が INNER JOIN です。両方のテーブルで結合条件を満たす行だけが結果に残ります。

query.sql
SELECT orders.id, customers.name, orders.amount
FROM orders
INNER JOIN customers
  ON orders.customer_id = customers.id;

ON のあとに結合条件(どの列とどの列が対応するか)を書きます。この例では、注文3件それぞれに顧客名がついた結果が返ります。注文を1件も持たない顧客 Dave は、orders 側に対応行が無いため結果に現れません。

なお、INNER JOININNER は省略でき、単に JOIN と書いても同じ意味になります。

LEFT JOIN — 左側は必ず残す

「注文が無い顧客も含めて、全顧客を一覧したい」場合は LEFT JOIN を使います。LEFT JOIN は、左側のテーブルの行はすべて残し、右側に対応する行が無ければ NULL で埋めます。

query.sql
SELECT customers.name, orders.amount
FROM customers
LEFT JOIN orders
  ON customers.id = orders.customer_id;

この結果では、注文を持たない Dave も amountNULL の行として現れます。「まだ一度も注文していない顧客」を探すといった用途で活躍します。

NULL を別の値に置き換えたいときは COALESCE が便利です。

query.sql
SELECT customers.name, COALESCE(SUM(orders.amount), 0) AS total
FROM customers
LEFT JOIN orders
  ON customers.id = orders.customer_id
GROUP BY customers.name;

JOIN の種類まとめ

種類残る行
INNER JOIN両方に一致する行だけ
LEFT JOIN左テーブルは全部+右は一致分(無ければ NULL)
RIGHT JOIN右テーブルは全部+左は一致分(無ければ NULL)
FULL OUTER JOINどちらかにあれば残す

実務では INNER JOINLEFT JOIN の2つで大半をカバーできます。RIGHT JOIN は左右を入れ替えれば LEFT JOIN で書けるため、使う場面は限られます。

3つ以上のテーブルを結合する

JOIN は続けて書くことで、3つ以上のテーブルもつなげます。たとえば「注文」「顧客」「商品」を結合する場合です。

query.sql
SELECT customers.name, products.name, order_items.quantity
FROM orders
JOIN customers   ON orders.customer_id = customers.id
JOIN order_items ON order_items.order_id = orders.id
JOIN products    ON order_items.product_id = products.id;

テーブル名が長くなってきたら、別名(エイリアス)を付けると読みやすくなります。

query.sql
SELECT c.name, p.name, oi.quantity
FROM orders o
JOIN customers   c  ON o.customer_id = c.id
JOIN order_items oi ON oi.order_id = o.id
JOIN products    p  ON oi.product_id = p.id;

まとめ

  • テーブルは意味のまとまりで分け、外部キーでつなぐ
  • INNER JOIN は両方に一致する行だけ、LEFT JOIN は左を必ず残す
  • 結合条件は ON で「どの列とどの列が対応するか」を書く
  • 複数テーブルは JOIN を続け、別名で読みやすくする

結合は SQL の中でもつまずきやすいところですが、「どちらのテーブルを基準に、何を残したいか」を意識すると選びやすくなります。「結合(JOIN)」カテゴリの演習問題で、実際に手を動かして確認してみてください。

手を動かして確認しましょう「結合(JOIN)」の演習問題で、実際に SQL を書いて自動採点できます。
問題一覧へ →