なぜ結合が必要か
このレッスンで分かること
- 結合 (
JOIN) は別テーブルに散らばった情報を共通キーでつなぐ操作ですON 条件で結合キーを明示、忘れるとデカルト積になります- 最小例は
SELECT o.id, c.name FROM orders o JOIN customers c ON o.customer_id = c.id;
なぜ結合が必要か とは
複数のテーブルから関連するデータを取得するために結合が必要な理由を解説します。本レッスンでは、なぜ結合が必要か の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。
なぜ重要か
リレーショナルデータベースは「データの重複を避ける」ために、情報を複数のテーブルに分けて保存します。たとえば注文情報は orders に、顧客情報は customers に、商品情報は products に分かれて存在します。実務でレポートを書くとき、ほぼ必ず複数のテーブルの情報を組み合わせる必要があります。その「組み合わせ」を行うのが結合 (JOIN) です。結合を理解しないと、SELECT 単体でできるのは「単一テーブルの一覧表示」だけになり、ビジネスで役立つクエリはほとんど書けません。SQL を学ぶ上で最大の壁が JOIN だとよく言われますが、ここを乗り越えれば実務レベルの SQL が一気に書けるようになります。
JOIN を一言でいうと「別々のテーブルに散らばった情報を、共通の列でつなぎ直す操作」です。orders と customers を customer_id でつなぐ、と考えると腑に落ちます。
正規化と結合の関係
データベース設計では、同じ情報を 1 ヶ所だけに持たせる「正規化」が基本です。顧客名を orders テーブルにも書いてしまうと、名前が変わったときに全注文行を書き換えないといけません。さらに、書き忘れがあれば「同じ顧客なのに違う名前」というデータの不整合が発生します。そこで orders は customer_id だけを持ち、名前は customers テーブルから引いてきます。この引いてくる操作が結合です。正規化は「データの整合性」、結合は「正規化されたデータを使うための窓口」と覚えると、両者の関係が腹落ちします。
SQL クエリ
-- 正規化された設計
CREATE TABLE customers (id INT, name VARCHAR(50));
CREATE TABLE orders (id INT, customer_id INT, amount INT);ステップごとの動作
結合は「2 つの表を、共通のキーを使って横につなぐ」操作です。下の図は orders と customers を customer_id で結合する流れを表しています。
図の流れを順序リストで書き直すと、次の通りです。
ordersテーブルからcustomer_idを含む行を読むcustomersテーブルからidを含む行を読む- 結合エンジンが
ON orders.customer_id = customers.idを評価する - 一致する行同士を横にくっつける
- 結合後の表として「注文 ID + 顧客名 + 金額」が並ぶ
SQL の世界では「結合キー」と「結合条件」を ON 句で明示します。ON orders.customer_id = customers.id のように書くのが基本形です。ON 句に書かれた条件を満たす行同士だけが横にくっつき、満たさない行は (結合の種類によって) 落ちるか NULL で埋められます。
代表例 1 — 結合しないと見えないもの
結合を使わずに「注文ごとの顧客名」を出すとどうなるかを見てみましょう。
SQL クエリ
-- 結合なしだと customer_id しかわからない
SELECT id, customer_id, amount FROM orders;この結果には customer_id = 1 のような数字しか出ず、それが誰なのかわかりません。レポートとして渡しても「ID 1 って誰?」と聞き返されるだけです。
代表例 2 — 結合で人が読める形に
結合を使うと、関連する顧客名を一緒に取得できます。
SQL クエリ
-- 結合を使うと名前まで取れる
SELECT o.id, c.name, o.amount
FROM orders o
JOIN customers c ON o.customer_id = c.id;結果は「注文 ID・顧客名・金額」が横並びになり、人間が読めるレポートになります。1 つの SQL で複数の表の情報を組み立てられるのが、リレーショナルデータベースの強さです。
結合の種類の早見
| 結合 | 残るレコード |
|---|---|
| INNER JOIN | 両方のテーブルに一致がある行だけ |
| LEFT OUTER JOIN | 左テーブルは全部残し、右にないものは NULL |
| RIGHT OUTER JOIN | 右テーブルを全部残す |
| CROSS JOIN | 全組み合わせ (デカルト積) |
| SELF JOIN | 同じテーブルを別名で結合 |
この章では INNER / OUTER / SELF / 集合演算を順番に学んでいきます。それぞれの違いを「どの行が残るか」で覚えるのがコツです。
よくある落とし穴
ON 句を忘れると「デカルト積」になり、行数が爆発します。10 行と 100 行のテーブルを結合キーなしで結合すると 1000 行になります。本番では数百万行 × 数百万行になりサーバが止まることもあります。
結合キーの型が違うと正しく結合できません。片方が VARCHAR で片方が INT だと、暗黙の型変換でインデックスが効かなくなり、極端に遅くなります。データモデル設計時に型を合わせるのが鉄則です。
customer_idのような外部キーは、相手の主キーと同じ型・同じ長さで揃えましょう。
実務での頻出パターン
結合は単独で使うことよりも、SELECT・WHERE・GROUP BY・ORDER BY と組み合わせて使うほうが大きくに多いです。例えば「最近 30 日に注文した顧客のうち、合計金額が 10000 円以上の人だけを抽出する」というレポートでは、結合 + フィルタ + 集計 + 並び替えが 1 つの SQL に全部入ります。最初のうちは段階を踏んで書き、慣れてきたら一気に書けるようにしていきましょう。
ここまでの要点
JOIN ... ON 条件 で 2 表をつなぐ。ON を忘れるとデカルト積で爆発。結合キーの型は両側で揃える。INNER は一致行だけ、OUTER は片側を全部残す。
まとめ
- 正規化されたテーブルは結合を前提に設計されている
- 結合は
ON句で「どのキーで合わせるか」を明示する - INNER / OUTER / SELF など複数の種類があり、用途に応じて使い分ける
ONを忘れるとデカルト積になり大事故になるので注意- 結合キーの型は両側で揃えてインデックスを効かせる
- 実務では結合 + フィルタ + 集計 + 並び替えがワンセットで使われる
次のレッスン
次は INNER JOINの基本 です。複数のテーブルを組み合わせてデータを取得するINNER JOINを学びます。
事前確認 — 進む前に次の 3 つができることを確認しましょう。
- 結合の必要性 の要点を自分の言葉で説明できる
- このレッスンの最小コード (または操作手順) を見ずに書ける
- 練習問題やクイズで間違えた箇所を読み直して理解した
理解度チェック (30 秒)
Q. 結合の必要性 とは何か、1 文で説明してください。
A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。
関連レッスン
テーブル構造
schema.sql
CREATE TABLE customers (
id INT PRIMARY KEY,
name VARCHAR(50)
);
CREATE TABLE orders (
id INT PRIMARY KEY,
customer_id INT,
amount INT
);
INSERT INTO customers VALUES
(1, '田中'),
(2, '鈴木'),
(3, '佐藤');
INSERT INTO orders VALUES
(101, 1, 3000),
(102, 2, 1500),
(103, 1, 2000),
(104, 3, 5000);期待される出力
| order_id | customer_name | amount |
|---|---|---|
| 101 | 田中 | 3000 |
| 102 | 鈴木 | 1500 |
| 103 | 田中 | 2000 |
| 104 | 佐藤 | 5000 |