SQLのJOIN(結合)を完全攻略!INNER JOINとLEFT JOINの違いを初心者向けに徹底解説
生徒
「データベースの勉強を始めたのですが、複数の表をくっつける『JOIN(ジョイン)』というところでつまずいています。種類が多すぎて、何が違うのかサッパリです……。」
先生
「確かに、JOINはSQLの学習で最初にぶつかる大きな壁ですね。でも、実は考え方はとてもシンプルなんですよ。今回は一番よく使う『INNER JOIN(内部結合)』と『LEFT JOIN(外部結合)』の違いに絞って、イメージを膨らませながら見ていきましょう。」
生徒
「内部とか外部とか、言葉が難しそうで不安です。パソコンの専門用語が苦手な私でもわかりますか?」
先生
「大丈夫です。パズルのピースを合わせるようなものだと思ってください。ぴったり合うものだけを繋げるのか、片方を大事に残しながら繋げるのか。具体的な例を使って、紙の名簿を整理するように解説しますね。」
1. SQLとは何か?
SQLは、データベースと呼ばれる「大量のデータを整理して保存する箱」に対して指示を出すための言語です。例えば、会員名簿の中から特定の人を探したり、新しい人を追加したりするときに使います。プログラミングと聞くと難しく感じるかもしれませんが、SQLは「この表から、これを持ってきて」という命令を英語に近い形で書くだけなので、初心者の方でも習得しやすいのが特徴です。
現代のインターネットサービスの裏側では、必ずと言っていいほどこのSQLが動いています。Amazonで買い物をするとき、Twitterで投稿を見るとき、これらはすべてデータベースからSQLを使ってデータを取得しているのです。まずは「表を操作するための魔法の言葉」として覚えておきましょう。
2. なぜ表を「結合(JOIN)」する必要があるの?
データベースの世界では、一つの大きな表にすべての情報を詰め込むことはしません。情報を整理整頓するために、あえて表を細かく分けて保存します。例えば、「注文した人の情報」が入った表と、「売っている商品の情報」が入った表を別々に作ります。これを「正規化(せいきか)」と呼びます。バラバラに保存しておくことで、後から住所が変わったときに一箇所だけ直せば済むなど、管理がとても楽になるからです。
しかし、実際にデータを見るときは、バラバラのままだと不便です。「誰が何を買ったか」を一覧で見たいときは、このバラバラの表を一時的に「合体」させる必要があります。この合体作業のことを、SQLでは「JOIN(ジョイン)」と呼びます。JOINをマスターすれば、複雑なデータから必要な情報を自由自在に引き出せるようになります。
3. INNER JOIN(内部結合)の使い方を学ぼう
まずは「INNER JOIN(インナージョイン)」について解説します。日本語では「内部結合」と呼びます。これは、二つの表を見比べて「両方の表に共通して存在しているデータだけ」を合体させて取り出す方法です。いわば、相思相愛のデータだけを抽出する、厳選されたリストアップ方法です。
具体的な例で見てみましょう。ここに「学生名簿(students)」と「部活動リスト(clubs)」の二つの表があります。学生の中には部活に入っていない人もいますし、部活動リストの中にはまだ部員がいない部活があるかもしれません。
id | name | club_id
---+----------+---------
1 | 田中太郎 | 10
2 | 佐藤花子 | 20
3 | 鈴木一郎 | NULL
4 | 高橋愛美 | 10
id | club_name | room
---+-----------+---------
10 | 野球部 | 第1グラウンド
20 | 吹奏楽部 | 音楽室
30 | 帰宅部 | なし
ここで、「部活に所属している学生と、その部活名を知りたい」という時にINNER JOINを使います。部活に入っていない鈴木一郎さん(club_idが空っぽ)や、部員がいない「30番の帰宅部」は、両方に共通するデータがないため、結果には表示されません。
それでは、実際のSQLコードを見てみましょう。
SELECT students.name, clubs.club_name
FROM students
INNER JOIN clubs
ON students.club_id = clubs.id;
この命令を実行した結果は以下のようになります。
name | club_name
---------+-----------
田中太郎 | 野球部
佐藤花子 | 吹奏楽部
高橋愛美 | 野球部
どうでしょうか?「両方の表にデータがある人だけ」が綺麗に並びましたね。これがINNER JOINの仕組みです。
4. LEFT JOIN(左外部結合)とは?
次に「LEFT JOIN(レフトジョイン)」についてです。日本語では「左外部結合」と言います。これは「左側(先)に書いた表のデータは、相手がいなくても全部表示する。相手がいればその情報をくっつける」という方法です。たとえ片想いであっても、左側のデータは絶対に見捨てない、優しい合体方法だと考えてください。
先ほどの学生名簿と部活動リストを例に、「全学生の名前と、もし入っていれば部活名を表示する」という状況を想定してみましょう。部活に入っていない鈴木一郎さんも、名簿には載せておきたい場合にLEFT JOINを使います。
SELECT students.name, clubs.club_name
FROM students
LEFT JOIN clubs
ON students.club_id = clubs.id;
実行結果は次のようになります。SQLを実行する前の元の表は、先ほどの「INNER JOIN」の時と同じものを使っています。
name | club_name
---------+-----------
田中太郎 | 野球部
佐藤花子 | 吹奏楽部
鈴木一郎 | NULL
高橋愛美 | 野球部
注目すべきは、鈴木一郎さんの行です。部活動リストには彼のIDに対応するデータがありませんが、LEFT JOINを使ったことで消えずに残っています。その代わり、部活名のところには「NULL(ヌル)」という言葉が入っています。これはIT用語で「何も入っていない、空っぽ」という意味です。
5. 集計(GROUP BY)を組み合わせてデータを分析しよう
JOINを使って表をくっつけたら、次は「集計」をしてみたくなります。例えば、「部活ごとに何人の学生が所属しているか」を数える場合です。ここで使うのが「GROUP BY(グループバイ)」と「COUNT(カウント)」という命令です。
GROUP BYは、指定した項目(今回の場合は部活名)でデータをグループ分けする機能です。COUNTは、そのグループの中にいくつデータがあるかを数える機能です。これらをJOINと一緒に使うことで、実務でよく使われる「データの集計レポート」が作れるようになります。
SELECT clubs.club_name, COUNT(students.id) AS member_count
FROM clubs
LEFT JOIN students
ON clubs.id = students.club_id
GROUP BY clubs.club_name;
このSQLでは、部活リスト(clubs)を左側に持ってきました。これにより、部員が0人の部活も含めて、すべての部活の人数を集計できます。
club_name | member_count
----------+--------------
野球部 | 2
吹奏楽部 | 1
帰宅部 | 0
このように、JOINと集計を組み合わせることで、「野球部には2人、吹奏楽部には1人、帰宅部には誰もいない」という有益な情報を取り出すことができました。これはビジネスの現場でも、売上分析やユーザー分析などで毎日使われている非常に重要なテクニックです。
6. INNER JOINとLEFT JOINの使い分けのコツ
では、どちらを使えばいいのか迷った時の判断基準をお伝えします。ポイントは「欠けているデータを見たいかどうか」です。
例えば、ECサイト(ネットショップ)の管理画面を想像してください。
- INNER JOINを使うとき:「商品を購入したお客様だけのリストを作りたい」場合。購入履歴がない人はリストに出したくないので、両方の表にデータがある人だけを抽出します。
- LEFT JOINを使うとき:「すべてのお客様のリストを作り、購入履歴がある人にはその内容を表示したい」場合。一度も買い物をしていないお客様も名簿から消したくないので、左側の顧客表を全て残します。
このように、「絶対に存在するデータだけが欲しいのか」、それとも「基本のリストは全部出した上で、関連情報があれば添えたいのか」という目的の違いで選ぶのがプロのやり方です。最初は混乱するかもしれませんが、何度も表を書いてイメージを練習すれば、自然と使い分けられるようになりますよ。