SQL JOIN — 2つの表を、どこまで残してくっつける?
データベースの表は、わざと小さく分けて持つのがふつうです(正規化)。「社員」表と「部署」表が別々にあると、「誰がどの部署か」を1枚にまとめて見たいときに困ります。そこで2つの表を共通の列(キー)でくっつけるのが JOIN(結合)です。
やっかいなのは、片方にしか存在しない行をどう扱うか。部署が未設定の社員や、社員が1人もいない部署を「残すか/捨てるか」で、JOINには4つの型があります。下の図1で INNER / LEFT / RIGHT / FULL を切り替えて、どの行が残り、足りないところが NULL になる様子を見てください。
SELECT * FROM 社員 INNER JOIN 部署 ON 社員.部署ID = 部署.id;
| id | 名前 | 部署ID |
|---|---|---|
| 1 | 田中 | 10 |
| 2 | 佐藤 | 20 |
| 3 | 鈴木 | なし |
| id | 部署名 |
|---|---|
| 10 | 営業部 |
| 20 | 開発部 |
| 30 | 総務部 |
| 社員.名前 | 社員.部署ID | 部署.id | 部署名 |
|---|---|---|---|
NULL で埋まる(社員=橙ハイライト / 部署=青ハイライトが「残る行」)「どちらを全部残すか」で名前が決まる
4つの違いは、結局「マッチしない行を残すか」だけです。INNERは両方にマッチした行だけ(交わり)。LEFTは左の表を全部残し、右に相手がいなければ右側をNULLに。RIGHTはその逆で右を全部残す。FULL OUTERは左も右も全部残し、相手のいない行は反対側がNULLになります。図1で 鈴木(部署なし)と 総務部(社員なし)が、型によって現れたり消えたりするのが要点です。
実務でいちばん多いのは INNER と LEFT です。「関連づくものだけ欲しい」なら INNER、「主役の表(左)は1行も落としたくない」なら LEFT を選びます。たとえば「全社員を一覧し、部署が未設定の人も漏らさず出す」なら LEFT JOIN。逆に INNER にすると、部署未設定の社員はしれっと消えてしまう —— この“いつの間にか行が減る”が、JOINでいちばんやりがちな事故です。
- JOIN
- 共通の列(キー)を手がかりに、複数の表を横につなげて1枚にする操作。
- INNER JOIN
- 両方の表でマッチした行だけを残す(交わり)。
- LEFT / RIGHT
- 片方の表を全部残し、相手がいなければ反対側を NULL で埋める外部結合。
- NULL
- 「値が無い」を表す印。外部結合で相手が見つからなかった列に入る。
まとめ
JOINは「分けて持った表を、キーでくっつけて1枚にする」操作。型の違いはマッチしない行の扱いだけで、INNERは捨て、LEFT/RIGHTは片側を残し、FULLは両方残します。図1で型を切り替えて、結果の行数と NULL の出方がどう動くかを目で覚えてください。「行が増えた/減った」の理由がJOINで説明できれば、SQLの怖さはかなり減ります。