SQL練習室
← SQLガイド

SQLのINNER JOINとは?2つの表を結ぶ基本を実行結果で解説

INNER JOINは、2つの表から条件に合う行同士を結び付ける構文です。たとえば、注文の表に顧客名がなくても、顧客の表と結ぶと「誰の注文か」を表示できます。まずは小さな2つの表で、どの行がつながるかを見てみましょう。

例で使う表

このページでは、次の顧客3件と注文3件を使います。ordersのcustomer_idは、注文した顧客の番号です。注文101と102は顧客1の青木商店、注文103は顧客2の北野物産に対応します。顧客3の中央商事には注文がありません。

customers:顧客の一覧
id(顧客ID)name(顧客名)
1青木商店
2北野物産
3中央商事
orders:注文の一覧
id(注文ID)customer_id(注文した顧客のID)amount(金額)
101112000
10218000
103225000

INNER JOINの基本構文

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

INNER JOINで注文に顧客名を付ける

やりたいことは、顧客名・注文ID・金額を同じ行に並べることです。FROM customersで顧客の表を指定し、INNER JOIN ordersで注文の表を結びます。ON customers.id = orders.customer_idは「顧客IDが同じ行同士を組み合わせる」という条件です。SELECTには、結果に表示したい列を書きます。

sql
SELECT customers.name, orders.id, orders.amount
FROM customers
INNER JOIN orders
  ON customers.id = orders.customer_id
ORDER BY orders.id;
実行結果
nameidamount
青木商店10112000
青木商店1028000
北野物産10325000

ONでどの行が結び付いたかを確かめる

青木商店のidは1です。注文101と102もcustomer_idが1なので、それぞれ青木商店と結び付きます。下のSQLでは比較した2つのIDも表示しています。customers.idは「顧客の表のid」、orders.idは「注文の表のid」です。同じidという列名でも、意味が違うので表の名前を付けて区別します。

sql
SELECT customers.id, customers.name,
  orders.customer_id, orders.amount
FROM customers
INNER JOIN orders
  ON customers.id = orders.customer_id
ORDER BY orders.id;
実行結果
idnamecustomer_idamount
1青木商店112000
1青木商店18000
2北野物産225000

同じ顧客名が2行出るのはなぜ?

青木商店には注文が2件あるので、結果にも青木商店が2行出ます。それぞれ注文101と注文102を表しており、同じ注文が二重に表示されたわけではありません。INNER JOINは条件に合う組み合わせをすべて返します。顧客1件につき結果も1行になるとは限りません。

sql
SELECT customers.name, orders.id, orders.amount
FROM customers
INNER JOIN orders
  ON customers.id = orders.customer_id
WHERE customers.id = 1
ORDER BY orders.id;
実行結果
nameidamount
青木商店10112000
青木商店1028000

一致する注文がない顧客は結果に出ない

中央商事のidは3ですが、ordersにはcustomer_idが3の注文がありません。結び付く相手がないため、最初の結果表に中央商事は出てきません。次のSQLで中央商事だけを指定しても、結果は0行です。元の顧客データが削除されるわけではありません。

sql
SELECT customers.name, orders.id, orders.amount
FROM customers
INNER JOIN orders
  ON customers.id = orders.customer_id
WHERE customers.id = 3;
実行結果
nameidamount

結果は0行です。

慣れたらASで表の名前を短くする

ここまでのcustomersをc、ordersをoと短く書くこともできます。FROM customers AS cと書くと、このSQLの中ではcがcustomersの別名になります。下のSQLは最初のSQLと同じ結果です。まずは省略しない形で理解してから、別名を使うと読みやすくなります。

sql
SELECT c.name, o.id, o.amount
FROM customers AS c
INNER JOIN orders AS o
  ON c.id = o.customer_id
ORDER BY o.id;
実行結果
nameidamount
青木商店10112000
青木商店1028000
北野物産10325000

実際に1問解いてみる

INNER JOIN・ON

注文に対応する顧客を結び、注文id、顧客名、注文額をこの順で取得してください。行順は問いません。

テーブル

読み込み中…

実行結果

関連構文

INNER JOINについてよくある質問

JOINとINNER JOINは同じですか?
はい。PostgreSQLではINNERを省略してJOINと書いても同じ意味です。このページでは結合の種類が分かるようにINNER JOINと書いています。
ONでは同じ名前の列を指定する必要がありますか?
いいえ。この例ではcustomers.idとorders.customer_idのように、名前が違っていても同じ顧客を表すIDを比較します。列名が同じかどうかではなく、何の値かを確認して結びます。

参考文献

内容はPostgreSQL公式ドキュメントを参照し、初めて学ぶ人向けに日本語で整理しています。