0Pricing
SQL Interview Prep · レッスン

JOINにおけるONとWHEREの違い

述語をONとWHEREのどちらに置くべきか、また結果にどう影響するかを学びます。

「JOINにおけるONとWHEREの違い」はCoddyKit上の無料SQL Interview Prepレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSQL Interview Prep学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 SQL Interview Prepコースには全4レッスンが含まれています。

述語は2か所に置けます

INNER JOINを書けるようになると、次の面接問題はさらに踏み込んだものになります。この条件はONとWHEREのどちらに置くべきでしょうか。

INNER JOINでは、結果については「どちらでも変わらない」ことがよくあります。しかし、外部結合に切り替えた瞬間、その選択によって結果は完全に変わります。初学者は習慣的にすべてをWHEREに書いてしまうため、面接官はまさにこの点を質問します。

このレッスンでは、そのルールを明確に説明します。

ONの役割

ON句は、行をどのように組み合わせるかを定義します。結合を構築する際に評価され、左テーブルのどの行と右テーブルのどの行を一致させるかを決めます。

ONは、「この2つの行は一緒に扱うべきか」という質問に答えるものだと考えてください。

SELECT c.name, o.amount
FROM customers c
JOIN orders o
  ON o.customer_id = c.id;   -- pairing rule

WHEREの役割

WHERE句は、結合によって結合済みの行が生成された後に評価されます。結果セットをフィルタリングし、条件を満たさない行を破棄します。

WHEREは、「行を結合した今、どの行を残したいか」という質問に答えるものだと考えてください。

SELECT c.name, o.amount
FROM customers c
JOIN orders o ON o.customer_id = c.id
WHERE o.amount > 30;   -- filter after pairing

INNER JOINでは多くの場合同じ結果になります

INNER JOINでは、追加のフィルターをONとWHEREのどちらに置いても、結果は同じになります。次の2つのクエリは、Adaの$50の注文とBobの$99の注文だけを返します。

一致しない行はINNER JOINによってすでに除外されるため、述語を移動しても残る行は変わりません。

-- predicate in ON
SELECT c.name, o.amount FROM customers c
JOIN orders o
  ON o.customer_id = c.id AND o.amount > 30;

-- predicate in WHERE -- same result here
SELECT c.name, o.amount FROM customers c
JOIN orders o ON o.customer_id = c.id
WHERE o.amount > 30;

それでも結合キーをONに置く理由

結果が同じ場合でも、慣例として、結合関係の条件はONに、ビジネス上のフィルターはWHEREに記述します。

  • ON: o.customer_id = c.id(テーブル同士の関係)
  • WHERE: o.amount > 30(必要な結果の条件)

この分離により、次に読む人にも、コードの書き方を評価する面接官にも、意図が明確に伝わります。

本当に重要になる場面: 外部結合

LEFT JOINでは、この違いが決定的になります。LEFT JOINは、右側に一致する行がない場合でも、左側のすべての行を残します。ここでは、注文のないCleoを含む顧客と注文の例を簡単に確認します。

LEFT JOINでは、注文のカラムがNULLになった状態でCleoも残ります。では、ONとWHEREがCleoに対してどのように作用するかを見てみましょう。

SELECT c.name, o.amount
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id;
-- keeps Ada, Bob, AND Cleo (NULL amount)

ONでフィルター: 行が保持される

amount > 30という条件をLEFT JOINのONに置くと、右側のどの行を付加するかだけに影響します。一致しない左側の行は、NULLを伴った状態で引き続き保持されます。

Cleoは残ります。条件を満たさない注文は付加されず、NULLのままになります。

SELECT c.name, o.amount
FROM customers c
LEFT JOIN orders o
  ON o.customer_id = c.id AND o.amount > 30;
-- Ada 50, Bob 99, Cleo NULL  (3 rows, Cleo kept)

WHEREでフィルター: 外部結合が崩れる

同じ条件をWHEREに移すと、結合済みの結果がフィルタリングされます。Cleoの行ではamount = NULLとなり、NULL > 30はtrueではないため、Cleoは除外されます。

LEFT JOINが、気付かないうちにINNER JOINのように動作します。これは面接で最も有名な結合の落とし穴です。

SELECT c.name, o.amount
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE o.amount > 30;
-- Ada 50, Bob 99  (Cleo GONE -> back to inner-join behavior)

覚えておくべきルール

面接では、次のように簡潔に説明してください。

  • ONの条件は、右側の行を付加するかどうかを決めます。左側の行は保持されます。
  • WHEREの条件は最終的な行をフィルタリングします。NULLになる可能性のあるカラムを対象にすると、保持されていた左側の行を除外することがあります。

したがって外部結合では、意図的に一致しない行を除外したい場合を除き、任意側のテーブルに対する述語はONに置きます。

WHEREでNULLを使う正当なケース

外部結合したカラムをWHEREでフィルタリングするのが正しいケースも1つあります。それがアンチ結合です。IS NULLで判定すると、一致する行がなかった左側の行を見つけられます。

ここではWHEREによって意図的に一致しない行だけを残し、注文数が0の顧客を返しています。同じ仕組みですが、目的は逆です。

SELECT c.name
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
WHERE o.id IS NULL;   -- customers with no orders -> Cleo

簡単なメンタルチェック

クイズの前に、結合条件を見たら次のチェックリストを確認してください。

  • テーブル同士を関連付ける結合キーですか。-> ON
  • 必須側のテーブルに対するフィルターですか。-> WHEREでもONでも問題ありません。
  • 任意側(外部結合側)のテーブルに対するフィルターで、一致しない行を残したいですか。-> ON
  • 一致しない行を見つけたいですか。-> WHERE ... IS NULL

確認問題

外部結合にONとWHEREのルールを適用してください。

まとめ: ONとWHERE

面接で説明できるよう、次の要点を押さえてください。

  • ONは行の組み合わせを制御します。また外部結合では、保持する側の行を残したまま、任意側の行を付加するかどうかを制御します。
  • WHEREは結合済みの結果をフィルタリングし、保持されていた行を除外することがあります。
  • INNER JOINでは両者を置き換えられることが多い一方、外部結合では置き換えられません。
  • 外部テーブルに対するフィルターは、WHEREでIS NULLを使ったアンチ結合を意図している場合を除き、ONに置きます。

よくある質問

「JOINにおけるONとWHEREの違い」レッスンは無料ですか?

はい。「JOINにおけるONとWHEREの違い」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、SQL Interview Prepコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 SQL Interview Prepコースには全4レッスンが含まれています。

「JOINにおけるONとWHEREの違い」で何を学びますか?

述語をONとWHEREのどちらに置くべきか、また結果にどう影響するかを学びます。 ブラウザで直接実行するハンズオンコードでSQL Interview Prepを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

SQL Interview Prepを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのSQL Interview Prepは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「JOINにおけるONとWHEREの違い」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このSQL Interview Prepレッスンでコードを書いて実行できますか?

はい。すべてのSQL Interview Prepレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. INNER JOINが行を照合する仕組み
  2. JOINにおけるONとWHEREの違い
  3. JOINのファンアウトと行の増加
  4. 3つ以上のテーブルをJOINする
← SQL Interview Prepに戻る