SQL結合(JOIN)
まず結論
JOINは複数のテーブルを関連するキー(外部キー)で結合するSQL構文です。INNER JOIN(内部結合)は両方に存在する行のみ、LEFT JOIN(左外部結合)は左テーブルを全件取得が試験の核心です。
サンプルテーブル
| 顧客テーブル(customers) | |
|---|---|
| id | name |
| 1 | 田中 |
| 2 | 鈴木 |
| 3 | 佐藤 |
| 注文テーブル(orders) | ||
|---|---|---|
| id | cust_id | amount |
| 101 | 1 | 5000 |
| 102 | 1 | 3000 |
| 103 | 2 | 8000 |
佐藤(id=3)は注文なし。ordersのcust_idがcustomers.idを参照(外部キー)
INNER JOIN(内部結合)
SELECT c.name, o.amount
FROM customers c
INNER JOIN orders o ON c.id = o.cust_id;
両方のテーブルに存在する行のみ取得。佐藤は注文がないので除外。
| name | amount |
|---|---|
| 田中 | 5000 |
| 田中 | 3000 |
| 鈴木 | 8000 |
LEFT JOIN(左外部結合)
SELECT c.name, o.amount
FROM customers c
LEFT JOIN orders o ON c.id = o.cust_id;
左テーブル(customers)を全件取得。右テーブルに対応なければNULL。
| name | amount |
|---|---|
| 田中 | 5000 |
| 田中 | 3000 |
| 鈴木 | 8000 |
| 佐藤 | NULL(注文なし) |
JOIN の種類まとめ
INNER JOIN
⊂∩⊃
両方に存在する行のみ
NULLなし
NULLなし
LEFT JOIN
◁—
左テーブル全件
右側はNULLあり
右側はNULLあり
RIGHT JOIN
—▷
右テーブル全件
左側はNULLあり
左側はNULLあり
CROSS JOIN:全ての組み合わせを生成(デカルト積)。m行×n行=m×n行の結果。ONなしのJOINと同じ。
🎯 試験での出方
- JOINを実行した結果の行数や内容を問う問題
- 「INNER JOINとLEFT JOINで結果が違う理由」→ 対応する行がないとき
- 「NULLが含まれる結合はどれか」→ LEFT/RIGHT/FULL JOIN(外部結合)
- ON句の結合条件を読んで正しい結果を選ぶ
⚠️ よくある間違い
- 「LEFT JOINは左テーブルだけを取得する」→ ✗ 左テーブル全件+右テーブルの一致行(一致しない場合NULL)
- 「INNER JOINとJOINは別物」→ ✗ JOINはINNER JOINの省略形(同じ)
- 「ONとWHEREは同じ」→ △ 外部結合でON条件とWHERE条件は意味が変わる(ONは結合条件、WHEREは結合後のフィルタ)
✍️ 確認クイズ
Q1. 上記サンプルで「SELECT c.name FROM customers c INNER JOIN orders o ON c.id = o.cust_id」の結果の行数はいくつか。
✅ 正解は②。INNER JOINなので両テーブルに存在する行のみ。田中は注文2件なので2行、鈴木は1件で1行、佐藤は注文なしで除外。合計3行ですが「田中、田中、鈴木」という内容。
Q2. LEFT JOINを使うとINNER JOINと比べてどのような結果になるか。
✅ 正解は②。LEFT JOINは左テーブルを全件保持します。右テーブルに対応する行がない場合はNULLになります。INNER JOINでは対応なしの行が除外されます。
Q3. 2つのテーブルを結合条件なしに全組み合わせで結合する場合の行数(A=3行, B=4行)はいくつか。
✅ 正解は②。CROSS JOIN(デカルト積)はm×n行になります。3行×4行=12行。ONなしのJOINまたはCROSS JOINと同じ結果です。
Q4. 「注文のない顧客を検索する」クエリとして正しいものはどれか。
✅ 正解は②。「注文のない顧客」はLEFT JOINでcustomersを全件取得し、ordersに対応がない行(o.id IS NULL)を探します。INNER JOINでは注文のない顧客は最初から除外されるため検索できません。このパターンは「どちらかのテーブルにしか存在しない行を探す」典型的なLEFT JOINの使い方です。
Q5. 上記サンプルで「SELECT c.name, SUM(o.amount) FROM customers c LEFT JOIN orders o ON c.id = o.cust_id GROUP BY c.name」の佐藤の合計amountはどれか。
✅ 正解は②。LEFT JOINで佐藤のamountはNULLになります。SUM(NULL)はNULL(0ではない)を返します。SUM()はNULLを無視して合計しますが、全てNULLの場合はNULLを返します。佐藤の行はLEFT JOINにより保持されるため③は不正解。NULLと0を混同しないことが重要です。
Sponsor Link