LEFT JOINと不一致行の保持
LEFT JOINで保持される行と、一致しない行にNULLが現れる仕組みを学びます。
「LEFT JOINと不一致行の保持」はCoddyKit上の無料SQL Interview Prepレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSQL Interview Prep学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 SQL Interview Prepコースには全4レッスンが含まれています。
面接での設定
面接官が次のように言ったとします。「注文したことがない顧客も含めて、すべての顧客とその注文を一覧表示してください。」 INNER JOIN では注文のない顧客が除外されるため、この要件を満たせません。ここで使うのが LEFT JOIN です。
LEFT JOIN は左側(最初に記述した)テーブルのすべての行を保持し、右側のテーブルに一致する行が存在する場合はそれを結合します。このレッスンでは、面接官が期待する正確なメンタルモデルを身につけます。
LEFT JOINが保証すること
基本的な約束は、左テーブルのすべての行が、一致するかどうかにかかわらず、出力に少なくとも1回現れることです。
- 左側の行に右側の一致が見つかる場合、一致ごとに1行の出力が得られます。
- 左側の行に一致がない場合でも、右テーブルのすべての列が
NULLに設定された出力行が1行得られます。
これが、面接官がこれを外部結合と呼ぶ理由です。一致集合の外側にある行も破棄せずに保持されます。
2つのテーブル
このレッスンでは、2つのシンプルなテーブルを使います。customers にはすべての顧客が含まれ、orders には購入記録が保存され、customer_id を介して顧客を参照します。
顧客3(Carol)には orders の行がありません。この一致しない顧客こそ、LEFT JOINが保持しなければならない対象です。
-- customers
-- id | name
-- 1 | Alice
-- 2 | Bob
-- 3 | Carol
-- orders
-- id | customer_id | amount
-- 10 | 1 | 50
-- 11 | 1 | 75
-- 12 | 2 | 20LEFT JOINを書く
構文はINNER JOINと同じで、INNER を LEFT に置き換えます(OUTER という語は省略可能です。LEFT JOIN と LEFT OUTER JOIN は同じ意味です)。
キーワードより前に記述されたテーブルが、保持される左側です。順序が重要です。customers LEFT JOIN orders はすべての顧客を保持しますが、すべての注文を保持するわけではありません。
SELECT c.name, o.amount
FROM customers c
LEFT JOIN orders o
ON o.customer_id = c.id;結果を読み取る
これがそのクエリの出力です。Aliceは2回一致したため、2回登場します。Bobは1回一致します。Carolは何にも一致しませんが、amount 列が NULL の状態で登場します。
NULLを持つCarolの1行が、LEFT JOINの特徴です。面接官が、あなたが声に出して考える様子を見ているなら、次のように説明することが求められます。「一致しない左側の行は、右側がNULLの状態で残ります。」
-- name | amount
-- Alice | 50
-- Alice | 75
-- Bob | 20
-- Carol | NULL <-- preserved, no matchNULLが生じる場所
NULL はどこかに保存されているわけではありません。右テーブルに amount を供給する行がないため、データベースが生成しています。
一致しない左側の行では、右テーブルから取得するすべての列が NULL になります。Carolの行では、o.id、o.customer_id、o.amount がすべてNULLです。これは重要です。o.customer_id がNULLであることは、顧客にIDがないという意味ではなく、一致する注文がまったくなかったという意味です。
顧客ごとの注文数を数える
よくある追加質問は次のとおりです。「0件の顧客も含めて、顧客ごとの注文数を求めてください。」 LEFT JOINと COUNT を組み合わせれば実現できますが、* ではなく右テーブルの列を数ぶ必要があります。
COUNT(o.id) はNULLを無視するため、Carolは0になります。COUNT(*) では、生成されたNULL行も行として数えられるため、Carolが1になってしまいます。
SELECT c.name, COUNT(o.id) AS order_count
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
GROUP BY c.name;
-- Alice | 2
-- Bob | 1
-- Carol | 0COUNT(*)とCOUNT(column)の落とし穴
これは面接でよくあるひっかけ問題です。LEFT JOINの後では、一致しない左側の行も、右側の列がNULLの状態で結果に実際に存在します。
COUNT(*)はその行を数えるため、注文のない顧客に対して1を返します。COUNT(o.id)はNULLを飛ばすため、正しく0を返します。
真の0件を求める場合は、一致しない側でNULLになる列を必ず数えてください。
-- WRONG: Carol shows 1
SELECT c.name, COUNT(*) AS n
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
GROUP BY c.name;LEFT JOINで合計する
COUNT以外の集計も、生成されたNULLを穏やかに処理します。SUM はNULLを無視するため、一致しない顧客の結果はエラーではなく NULL になります。
レポートでは、NULLではなく0を求められることがよくあります。集計関数を COALESCE で囲み、既定値に置き換えてください。
SELECT c.name,
COALESCE(SUM(o.amount), 0) AS total_spent
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
GROUP BY c.name;
-- Alice | 125
-- Bob | 20
-- Carol | 0左テーブルと右テーブルを明確に説明する
面接官から「どちらのテーブルが保持されますか」と聞かれたら、自信を持って答えてください。JOINキーワードの左側にあるテーブルです。左から右へ読めば分かります。
A LEFT JOIN B は、Aをすべて保持するという意味です。Bをすべて保持するには、B LEFT JOIN A のように順序を入れ替えるか、RIGHT JOINを使います。多くのチームでは、読みやすさのためRIGHT JOINを使わず、テーブルの順序を入れ替えてLEFT JOINだけを使います。
メンタルチェックリスト
面接でLEFT JOINを見たら、次のチェックリストを声に出して確認してください。
- 保持される側は? 左テーブルで、すべての行が保持されます。
- 一致しない行は? 右側のNULLとともに1回現れます。
- 数える場合は? 真の0件を得るには
COUNT(right_col)を使います。 - 合計する場合は? NULLではなく0が必要なら
COALESCEで囲みます。
このチェックリストを言葉にして説明できると、シニアレベルの厳密さを示せます。
クイックチェック
カウントについて、LEFT JOINの直感を試してみましょう。
まとめ
LEFT JOINは左テーブルのすべての行を保持します。 一致する左側の行は右側の一致と組み合わされ、一致しない左側の行は、右テーブルのすべての列が NULL の状態で1回残ります。
- 左テーブルは
JOINキーワードの前にあるテーブルです。 - 生成されたNULLは、一致しない行を示します。
COUNT(right_col)は真の0件を返しますが、COUNT(*)は返しません。COALESCE(SUM(...), 0)はNULLの合計を0に変換します。
これは、これからのレッスンで扱う欠損データの検出とアンチ結合の基礎になります。
よくある質問
「LEFT JOINと不一致行の保持」レッスンは無料ですか?
はい。「LEFT JOINと不一致行の保持」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、SQL Interview Prepコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 SQL Interview Prepコースには全4レッスンが含まれています。
「LEFT JOINと不一致行の保持」で何を学びますか?
LEFT JOINで保持される行と、一致しない行にNULLが現れる仕組みを学びます。 ブラウザで直接実行するハンズオンコードでSQL Interview Prepを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
SQL Interview Prepを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのSQL Interview Prepは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「LEFT JOINと不一致行の保持」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このSQL Interview Prepレッスンでコードを書いて実行できますか?
はい。すべてのSQL Interview Prepレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。