SQL JOINを例で解説 (Inner・Left・Right・Full)
2つの小さなテーブル、分かりやすいクエリ、正確な結果で、INNER・LEFT・RIGHT・FULL・CROSS・SELF JOINを学びます。
- INNER JOIN:両方のテーブルで一致する行だけ。
- LEFT JOIN:左の全行と一致する行(なければNULL)。
- RIGHT JOIN:右の全行と一致する行。
- FULL JOIN:両方の全行を、可能な限り結び付けて返す。
- キーで結合し、テーブルエイリアスを使い、結合列にインデックスを作成する。
実際のデータベースは、すべてを1つのテーブルに入れません。顧客は1つのテーブル、注文は別のテーブルにあります。「今月注文した顧客は誰か」に答えるには両者を組み合わせる必要があり、それを行うのがSQL JOINです。
このガイドは実践的です。同じ2つのテーブルでも結合の種類で結果が変わるため、初心者は混乱しがちです。小さく具体的なデータで見れば簡単になります。
SQL JOIN解説:サンプルテーブル
customers
| id | name |
|---|---|
| 1 | Asha |
| 2 | Ben |
| 3 | Chitra |
orders
| id | customer_id | total |
|---|---|---|
| 101 | 1 | 250 |
| 102 | 1 | 120 |
| 103 | 2 | 90 |
| 104 | 9 | 40 |
Chitraには注文がなく、注文104は存在しない顧客(9)を指しています。この2つの境界ケースが結合の種類による違いを示します。
INNER JOIN
INNER JOINは、両方のテーブルで条件が成り立つ行だけを返します。相手のない行は除外されます。
SELECT c.name, o.id AS order_id, o.total
FROM customers c
INNER JOIN orders o ON o.customer_id = c.id;
結果:Asha(101)、Asha(102)、Ben(103)。Chitraと注文104は含まれません。顧客情報付きの注文のように、関連するデータだけが必要なときに使います。単にJOINと書くとINNER JOINの意味になります。
LEFT JOIN
LEFT JOINは左テーブルの全行を残し、右テーブルの一致する行を追加します。一致しない場合、右側の列はNULLになります。
SELECT c.name, o.id AS order_id, o.total
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id;
結果:Asha(101)、Asha(102)、Ben(103)、Chitra(NULL, NULL)。今度はChitraが表示されます。
ワンポイント:一度も注文していない顧客を探すには、右側のNULLで絞り込みます。WHERE o.id IS NULLでChitraが得られます。テスターは孤立したレコードや欠落したレコードを探すためにこれを使います。
RIGHT JOINとFULL JOIN
RIGHT JOINはLEFT JOINの鏡像で、右テーブルの全行を残します。多くの人はテーブルの順序を入れ替えて、読みやすいLEFT JOINを使います。
SELECT c.name, o.id AS order_id
FROM customers c
RIGHT JOIN orders o ON o.customer_id = c.id;
結果には、顧客名がNULLの注文104が含まれます。FULL(OUTER)JOINは両テーブルの全行を返します。注文のないChitraと、顧客のいない注文104の両方です。
SELECT c.name, o.id AS order_id
FROM customers c
FULL OUTER JOIN orders o ON o.customer_id = c.id;
PostgreSQLとSQL Serverは対応しています。MySQLは非対応なので、LEFT JOINとRIGHT JOINをUNIONで組み合わせます。詳しくはPostgreSQLマニュアルの分かりやすい結合のチュートリアルをご覧ください。
| 結合 | 左だけの行 | 右だけの行 | 一致する行 |
|---|---|---|---|
| INNER | なし | なし | あり |
| LEFT | あり | なし | あり |
| RIGHT | なし | あり | あり |
| FULL | あり | あり | あり |
CROSS JOINとSELF JOIN
CROSS JOINは、一方のテーブルのすべての行を他方のすべての行と組み合わせます。顧客3人と注文4件なら12行になります。あまり使いませんが、サイズと色ごとのテストデータなど、組み合わせの生成に便利です。
SELECT c.name, o.id
FROM customers c
CROSS JOIN orders o;
SELF JOINはエイリアスを使ってテーブルを自分自身と結合します。たとえば各従業員の上司を調べる場合です。
SELECT e.name AS employee, m.name AS manager
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.id;
SQL JOIN:よくある間違いとパフォーマンスのコツ
- ON句の書き忘れは意図せずCROSS JOINを作り、行数が爆発します。
- LEFT JOINの後でWHEREで右テーブルを絞り込むとINNER JOINになってしまいます。条件はONに書きましょう。
- 曖昧な列名:列名の前にテーブルエイリアスを付けます。
- 一意でない列での結合は行を増殖させ、合計を水増しします。
- 結合列にインデックスを作り、必要な列だけを選択し、遅いクエリは
EXPLAINで調べます。
テスターにとって結合が重要な理由
QAエンジニアは、UIやAPI経由で作成したデータがデータベースに正しく届いたかを確認したり、孤立したレコードを見つけたりするために結合を使います。PostmanによるAPIテストガイド(英語)と併せてお読みください。基本は初心者向けSQLチュートリアル(英語)、新しいデータストアはベクトルデータベース(英語)をご覧ください。データベースをローカルで動かすにはDockerチュートリアル(英語)が役立ちます。
まとめ
SQL JOINを一言で:INNERは一致のみ、LEFTは左のすべて、RIGHTは右のすべて、FULLはすべてを残します。実行前に結果を予想できるまで、2つの小さなテーブルで練習しましょう。その後、3つのテーブルを結合し、結合とGROUP BYを組み合わせてみてください。
よくある質問
INNER JOINとLEFT JOINの違いは何ですか?
INNER JOINは両方のテーブルで一致する行だけを返します。LEFT JOINは左テーブルの全行を返し、一致しない右側の列をNULLで埋めます。
最も速いSQL JOINはどれですか?
常に最速という種類はありません。性能はインデックス、テーブルサイズ、実行計画に左右されます。結合列にインデックスを作り、実行計画を確認してください。
MySQLはFULL OUTER JOINに対応していますか?
いいえ。MySQLでは、LEFT JOINとRIGHT JOINをUNIONで組み合わせると同じ結果が得られます。
SELF JOINは何に使いますか?
SELF JOINは同じテーブル内の行を比較します。たとえば1つのemployeesテーブルで各従業員の上司を探すときに使います。
なぜJOINで重複行が返ってくるのですか?
結合列がどちらかのテーブルで一意でない場合に重複が発生します。キーを確認するか、結合前にデータを集計してください。
さらに学ぶ(英語の記事)
テスト、WordPress、SEOでお困りですか?
チームがより良いソフトウェアを届け、サイトを成長させるお手伝いをしています。取り組み内容をお知らせいただければ、次のステップをご提案します。
詳しいガイドはこちら テスト、AI、最新の開発
この記事は気に入りましたか?トピックを選択して、最新のチュートリアルに直接アクセスしてください。
