STAGE 05 — 5-3 / テーブルの結合

LEFT JOINと外部結合

考えてみよう

ミドリはアマテラスに配属されたばかりで、まだ任務を1つも担当していません。crewテーブルとmissionsテーブルをINNER JOINしたら、ミドリの名前は結果に出てくるでしょうか、出てこないでしょうか?

INNER JOINは「両方の表に一致する行があるときだけ」つなげる結合でした。ミドリの側には、対応するmissionsの行がありません。予想してから読み進めてください。

INNER JOINの落とし穴

crewテーブルの全員と、missionsテーブルをINNER JOINしてみましょう。

SELECT crew.name, missions.title
FROM crew
INNER JOIN missions ON crew.id = missions.crew_id;

結果:

nametitle
ユミ金星大気観測
ケンジ火星資源調査
サクラケレス採掘権交渉
ハルトケレス医療支援
レイエウロパ生命探査
ソラタイタン氷床探査
リョウ火星コロニー建設支援

crewテーブルには10人いたはずなのに、結果には7人しか出てきません。ミドリ・トウマ・アカリの3人が消えています。この3人には対応するmissionsの行がないため、INNER JOINは「一致する行がない」と判断して、その行ごと結果から除いてしまうのです。

「全乗組員の稼働状況を一覧したい」ときに、これでは困ります。任務を持たない人ほど目に留めたいのに、INNER JOINだとまさにその人が結果から消えてしまうからです。

LEFT JOIN ― 相手がいなくても残す

そこで使うのがLEFT JOINです。

SELECT crew.name, missions.title
FROM crew
LEFT JOIN missions ON crew.id = missions.crew_id;

結果:

nametitle
ユミ金星大気観測
ケンジ火星資源調査
サクラケレス採掘権交渉
ハルトケレス医療支援
レイエウロパ生命探査
ミドリNULL
ソラタイタン氷床探査
トウマNULL
アカリNULL
リョウ火星コロニー建設支援

ミドリ・トウマ・アカリの3人が結果に残り、対応するmissionsの情報がない部分には NULL が入りました。FROM crew と先に書いた側(左側)のテーブルの行は、たとえ相手(missions)に一致する行がなくても、全部残す——これがLEFT JOIN(左外部結合)の意味です。「LEFT」は「FROM句の直後、つまり左に書いたテーブルを主役にする」という意味だと考えると分かりやすいでしょう。

NULLになる列

NULLは「0」でも「空文字」でもなく、「値が存在しない」ことを表す特別な状態です。ミドリの行の title がNULLなのは、「タイトルが空っぽの任務」があるのではなく、そもそも対応する任務の行自体がないことを表しています。

任務を持たない乗組員だけを探したいときは、こう書きます。

SELECT crew.name
FROM crew
LEFT JOIN missions ON crew.id = missions.crew_id
WHERE missions.title IS NULL;

結果:

name
ミドリ
トウマ
アカリ

NULLかどうかを調べるときは = NULL ではなく IS NULL と書くのがルールです。NULLは「値」ではなく「値がない状態」なので、= で比較すること自体ができません。

使いどころ

「今のデータで欠けがないか」「まだ何も紐づいていない行はどれか」を調べたいときこそ、LEFT JOINの出番です。

確認問題

crewテーブルとmissionsテーブルをLEFT JOINしたとき、任務を1つも持たない乗組員の行はどうなるでしょう?

答えを見る

その乗組員の行は結果に残り、missions側の列にはNULLが入ります

LEFT JOINは、FROMで指定した左側の表(この場合crew)の行を、相手(missions)に一致する行があってもなくても、すべて残す結合方法です。一致する行がなければ、右側の表の列はNULLで埋められます。

ゆみちゃん
ゆみ

INNER JOINは「両方そろってるものだけ」、LEFT JOINは「主役は全員出席、相手がいなければNULLで空席」——このイメージだけ持てれば大丈夫。これでSTAGE05のJOINは修了! 次はいよいよ、データそのものを追加・変更する「操作」の話に入るよ。

/sql/game/ の SQL DIVER で、INNER JOINとLEFT JOINの結果の違いを、実際にタイプして確かめてみましょう。同じ2つの表でも、JOINの種類ひとつで結果ががらりと変わる感覚を、ぜひ手を動かして体験してください。