INNER JOINとLEFT JOINの違い|図解でわかるSQLの結合
SQLの学習を進めていくと、ほぼ全員が同じ場所で立ち止まります。それが JOIN です。中でも INNER JOIN と LEFT JOIN の違いは、「なんとなくわかるけど、いざ使い分けようとすると自信がない」という声を本当によく聞きます。
この記事では、この2つの違いを、実際のデータで結果がどう変わるかを見ながら整理していきます。丸暗記ではなく、「なぜそうなるのか」が腑に落ちることを目指します。
そもそも、なぜJOINが必要なのか
まず、JOINがなぜ存在するのかから話させてください。ここがわかると、INNERとLEFTの違いも自然と見えてきます。
データベースでは、情報を種類ごとに別々のテーブルに分けて保存します。たとえばネットショップなら、「ユーザーの情報」と「注文の履歴」は別のテーブルです。
users テーブル
| id | name |
|---|---|
| 1 | 佐藤 |
| 2 | 鈴木 |
| 3 | 田中 |
orders テーブル
| id | user_id | item |
|---|---|---|
| 1 | 1 | 書籍 |
| 2 | 1 | ペン |
| 3 | 2 | ノート |
なぜ分けるのか。もし1つのテーブルに全部詰め込むと、佐藤さんが注文するたびに名前やメールアドレスを何度も繰り返し書くことになり、無駄が多く、修正も大変になるからです。だからデータは分けて保存し、必要なときに user_id のような「つなぐためのキー」でくっつける。このくっつける操作がJOINです。
さて、ここで注目してほしいのが田中さん(id: 3)です。orders テーブルを見ると、田中さんの注文はどこにもありません。この「一度も注文していない人」を、結果に含めるか含めないか——これこそが、INNER JOINとLEFT JOINを分ける決定的なポイントです。
INNER JOIN:両方に存在する行だけ
INNER JOIN は、結合条件を満たす行だけを返します。言い換えると、両方のテーブルに対応がある組み合わせだけが残ります。
SELECT users.name, orders.item
FROM users
INNER JOIN orders ON users.id = orders.user_id;
このクエリの結果は、こうなります。
| name | item |
|---|---|
| 佐藤 | 書籍 |
| 佐藤 | ペン |
| 鈴木 | ノート |
注目すべきは、田中さんが消えていることです。田中さんは注文がない= orders 側に対応する行がないため、INNER JOINの結果からはきれいに除外されます。「注文したことがあるユーザーだけを見たい」というときは、これが正解です。
LEFT JOIN:左のテーブルは全部残す
一方の LEFT JOIN は、左側(FROMで最初に書いたテーブル)の行をすべて残し、右側に対応がなければ空っぽ(NULL)で埋めます。
SELECT users.name, orders.item
FROM users
LEFT JOIN orders ON users.id = orders.user_id;
結果はこうです。
| name | item |
|---|---|
| 佐藤 | 書籍 |
| 佐藤 | ペン |
| 鈴木 | ノート |
| 田中 | NULL |
今度は田中さんが残りました。注文がないので item は NULL(空)になっていますが、ユーザーとしては結果に含まれています。「全ユーザーを見たい。ついでに注文の有無も知りたい」というときは、こちらを使います。
同じデータ、同じ結合キーなのに、INNERかLEFTかで田中さんの扱いが変わる。この一点さえ押さえれば、2つの違いはもう自分のものです。
使い分けの早見表
実務で迷ったときのために、判断基準を表にまとめておきます。
| やりたいこと | 使うJOIN |
|---|---|
| 注文したことがあるユーザーだけ見たい | INNER JOIN |
| 全ユーザーを見て、注文の有無も知りたい | LEFT JOIN |
| 「一度も注文していない人」を探したい | LEFT JOIN + WHERE orders.id IS NULL |
最後の行が地味に便利です。LEFT JOINで全員を残したうえで「右側がNULLの人」だけに絞れば、「注文ゼロのユーザー一覧」が作れます。休眠ユーザーの抽出などで実際によく使う手です。
つまずきやすいポイント
最後に、初心者がハマりがちな落とし穴を2つだけ。
その1:LEFT JOINなのに、なぜかINNER JOINと同じ結果になる
LEFT JOINで田中さんを残したはずなのに、WHERE 句に orders.item = '書籍' のような右テーブルの条件を書くと、NULLの田中さんが弾かれて消えてしまいます。せっかくLEFTにした意味がなくなるわけです。右テーブルへの条件は、WHERE ではなく ON 句側に書く、という選択肢も覚えておくと表現の幅が広がります。
その2:どっちが「左」か迷う
FROM users LEFT JOIN orders と書いたとき、左は users、右は orders です。FROMのすぐ後ろが左、と覚えておけば混乱しません。
頭で理解したら、手で確かめよう
ここまで読んで「わかった気がする」と感じたなら、それはとても良い状態です。ただ、JOINは特に実際にデータで結果を見比べたときに本当の理解が定着します。同じテーブルに対してINNERとLEFTを書き分けて、田中さんが消えたり残ったりするのを自分の目で確かめてみてください。
SQL Quest には、JOINを扱う練習問題が数多く用意されています。この記事のイメージを持ったまま、練習問題で手を動かしてみてください。「消える/残る」が自分の操作で再現できたとき、JOINはもう怖くなくなっているはずです。