SQL練習室
← SQLガイド

SQLのLEFT JOINとは?一致しない行を残す使い方とINNER JOINとの違い

LEFT JOINは、結び付く相手がなくても左側の表の行を残す構文です。「注文のない顧客も含めて一覧にしたい」ときに使います。INNER JOINと同じ顧客・注文の表で、結果の違いを確認しましょう。

例で使う表

このページでは、次の顧客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

LEFT JOINの基本構文

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

LEFT JOINで注文のない顧客も残す

FROM customersの顧客をすべて残し、条件に合う注文を結びます。中央商事には注文がないので、注文IDと金額はNULLになります。NULLはここでは「対応する注文の値がない」ことを表します。青木商店には2件の注文があるため、結果も2行です。

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

INNER JOINとの違いを結果で比べる

同じSQLのLEFT JOINをINNER JOINに変えると、注文のない中央商事が結果から消えます。注文のある顧客だけならINNER JOIN、注文の有無にかかわらず全顧客を出すならLEFT JOINを使います。

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に条件を加える:全顧客を残して1万円以上の注文を結ぶ

1万円以上の注文だけを付け、全顧客を残したい場合は、金額の条件もONに書きます。青木商店の8000円の注文は結合対象から外れますが、注文のない中央商事は残ります。

sql
SELECT customers.name, orders.id, orders.amount
FROM customers
LEFT JOIN orders
  ON customers.id = orders.customer_id
  AND orders.amount >= 10000
ORDER BY customers.id, orders.id;
実行結果
nameidamount
青木商店10112000
北野物産10325000
中央商事NULLNULL

WHEREに条件を書くと、結合後の行を絞る

同じ金額条件をWHEREに書くと、結合後の結果から1万円以上の行だけが残ります。中央商事の金額はNULLなので条件を満たさず、中央商事も結果から消えます。全顧客を残したい場合は、前の例のようにONに条件を置きます。

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

IS NULLで注文のない顧客を探す

LEFT JOINの後でorders.id IS NULLを指定すると、注文と結び付かなかった顧客だけを取り出せます。判定には注文IDのように、元の表でNULLにならない列を使います。ここではorders.idを主キーとしています。

sql
SELECT customers.id, customers.name
FROM customers
LEFT JOIN orders
  ON customers.id = orders.customer_id
WHERE orders.id IS NULL
ORDER BY customers.id;
実行結果
idname
3中央商事

関連構文

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

LEFT JOINの「左」はどの表ですか?
このページのように2つの表を結ぶ場合、FROMの直後に書いた表が左側です。全顧客を残したいので、customersをFROMの直後に置いています。
LEFT JOINとLEFT OUTER JOINは違いますか?
同じ意味です。OUTERは省略できるため、このページではLEFT JOINと書いています。

参考文献

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