NULL 保持・アンチジョイン・ON vs WHERE の落とし穴
一方のテーブルに一致する行がなくてもNULL を埋めて結果に残す結合。「全件残したい」テーブル側を LEFT/RIGHT で指定する。
SELECT c.顧客ID, c.顧客名, o.受注ID, o.金額 FROM 顧客 c LEFT OUTER JOIN 受注 o ON c.顧客ID = o.顧客ID;
| 顧客名 | 受注ID | 金額 |
|---|---|---|
| 山田 | 001 | 5,000 |
| 鈴木 | 002 | 12,000 |
| 佐藤(受注なし) | NULL | NULL |
LEFT に書いたテーブルの全行が必ず残る。一致しない右テーブルの列は NULL になる。
-- RIGHT JOIN FROM 受注 o RIGHT OUTER JOIN 顧客 c ON o.顧客ID = c.顧客ID -- 上記と同じ結果(テーブルの順序を入れ替えて LEFT に変換) FROM 顧客 c LEFT OUTER JOIN 受注 o ON c.顧客ID = o.顧客ID
SELECT c.顧客名, o.受注ID FROM 顧客 c FULL OUTER JOIN 受注 o ON c.顧客ID = o.顧客ID;
| 顧客名 | 受注ID | 状態 |
|---|---|---|
| 山田 | 001 | 両方一致 |
| 佐藤(受注なし) | NULL | 顧客のみ存在 |
| NULL | 099(顧客ID削除済) | 受注のみ存在 |
-- 受注が 1 件もない顧客を取得(アンチジョイン) SELECT c.顧客ID, c.顧客名 FROM 顧客 c LEFT JOIN 受注 o ON c.顧客ID = o.顧客ID WHERE o.受注ID IS NULL; -- 一致しなかった行だけ選ぶ
| 条件の場所 | 効果 | NULL 行の扱い |
|---|---|---|
| ON 句 | 結合の絞り込み(結合前に適用) | ✅ NULL 行が残る |
| WHERE 句 | 結合後の絞り込み | ❌ NULL 行が消える(INNER JOIN と同等) |
-- ON に書く → 受注なし顧客も残る FROM 顧客 c LEFT JOIN 受注 o ON c.顧客ID = o.顧客ID AND o.金額 >= 5000 -- WHERE に書く → 受注なし顧客が除外される FROM 顧客 c LEFT JOIN 受注 o ON c.顧客ID = o.顧客ID WHERE o.金額 >= 5000 -- NULL は条件を通過しない
読了ボタンを押すとトップページの進捗に反映されます