SQLのLEFT JOINとは?一致しない行を残す使い方とINNER JOINとの違い
LEFT JOINは、結び付く相手がなくても左側の表の行を残す構文です。「注文のない顧客も含めて一覧にしたい」ときに使います。INNER JOINと同じ顧客・注文の表で、結果の違いを確認しましょう。
例で使う表
このページでは、次の顧客3件と注文3件を使います。ordersのcustomer_idは、注文した顧客の番号です。注文101と102は顧客1の青木商店、注文103は顧客2の北野物産に対応します。顧客3の中央商事には注文がありません。
| id(顧客ID) | name(顧客名) |
|---|---|
| 1 | 青木商店 |
| 2 | 北野物産 |
| 3 | 中央商事 |
| id(注文ID) | customer_id(注文した顧客のID) | amount(金額) |
|---|---|---|
| 101 | 1 | 12000 |
| 102 | 1 | 8000 |
| 103 | 2 | 25000 |
LEFT JOINの基本構文
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行です。
SELECT customers.name, orders.id, orders.amount
FROM customers
LEFT JOIN orders
ON customers.id = orders.customer_id
ORDER BY customers.id, orders.id;| name | id | amount |
|---|---|---|
| 青木商店 | 101 | 12000 |
| 青木商店 | 102 | 8000 |
| 北野物産 | 103 | 25000 |
| 中央商事 | NULL | NULL |
INNER JOINとの違いを結果で比べる
同じSQLのLEFT JOINをINNER JOINに変えると、注文のない中央商事が結果から消えます。注文のある顧客だけならINNER JOIN、注文の有無にかかわらず全顧客を出すならLEFT JOINを使います。
SELECT customers.name, orders.id, orders.amount
FROM customers
INNER JOIN orders
ON customers.id = orders.customer_id
ORDER BY orders.id;| name | id | amount |
|---|---|---|
| 青木商店 | 101 | 12000 |
| 青木商店 | 102 | 8000 |
| 北野物産 | 103 | 25000 |
ONに条件を加える:全顧客を残して1万円以上の注文を結ぶ
1万円以上の注文だけを付け、全顧客を残したい場合は、金額の条件もONに書きます。青木商店の8000円の注文は結合対象から外れますが、注文のない中央商事は残ります。
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;| name | id | amount |
|---|---|---|
| 青木商店 | 101 | 12000 |
| 北野物産 | 103 | 25000 |
| 中央商事 | NULL | NULL |
WHEREに条件を書くと、結合後の行を絞る
同じ金額条件をWHEREに書くと、結合後の結果から1万円以上の行だけが残ります。中央商事の金額はNULLなので条件を満たさず、中央商事も結果から消えます。全顧客を残したい場合は、前の例のようにONに条件を置きます。
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;| name | id | amount |
|---|---|---|
| 青木商店 | 101 | 12000 |
| 北野物産 | 103 | 25000 |
IS NULLで注文のない顧客を探す
LEFT JOINの後でorders.id IS NULLを指定すると、注文と結び付かなかった顧客だけを取り出せます。判定には注文IDのように、元の表でNULLにならない列を使います。ここではorders.idを主キーとしています。
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;| id | name |
|---|---|
| 3 | 中央商事 |
関連構文
LEFT JOINについてよくある質問
- LEFT JOINの「左」はどの表ですか?
- このページのように2つの表を結ぶ場合、FROMの直後に書いた表が左側です。全顧客を残したいので、customersをFROMの直後に置いています。
- LEFT JOINとLEFT OUTER JOINは違いますか?
- 同じ意味です。OUTERは省略できるため、このページではLEFT JOINと書いています。
参考文献
内容はPostgreSQL公式ドキュメントを参照し、初めて学ぶ人向けに日本語で整理しています。
- PostgreSQL公式:テーブルの結合 — 結合条件、列の指定、別名の基本
- PostgreSQL公式:結合テーブル — INNER JOINとLEFT JOIN、ONとWHEREの仕様