LEFT/RIGHT OUTER JOIN

LEFT/RIGHT OUTER JOIN とは

LEFT/RIGHT OUTER JOINを使い、テーブル間の連携を深めましょう。本レッスンでは、LEFT/RIGHT OUTER JOIN の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。

なぜ重要か

実務では「対応するレコードがなくても、片側のテーブルは全件残したい」場面が頻繁にあります。たとえば「全顧客の購入金額レポート」を作りたいとき、まだ購入していない顧客も金額 0 で表示したい。INNER JOIN だと購入実績のない顧客が消えてしまうので、こんなときに使うのが OUTER JOIN (外部結合) です。LEFT / RIGHT / FULL の 3 種類がありますが、MySQL / TiDB では FULL は使えないので、実質 LEFT と RIGHT の使い分けを覚えれば足ります。OUTER JOIN は「未対応データを可視化する」ためのツールでもあり、データ品質チェックや欠損レポートで重宝します。

LEFT OUTER JOIN の構文

SQL クエリ

SELECTFROM 左テーブル AS L LEFT OUTER JOIN 右テーブル AS R ON L.キー = R.キー;

OUTER は省略可で、LEFT JOIN だけでも同じ意味です。左テーブルの全行が必ず残り、右側に一致がない場合は NULL で埋められます。

ステップごとの動作

下の図は顧客テーブルと注文テーブルを LEFT JOIN する例です。注文を 1 件もしていない顧客も左側に残り、右側のカラムは NULL になります。

diagram (will load when visible)

代表例 1 — 注文未経験の顧客を見つける

SQL クエリ

SELECT c.id, c.name, o.id AS order_id FROM customers c LEFT JOIN orders o ON c.id = o.customer_id WHERE o.id IS NULL;

LEFT JOIN で全顧客を残し、WHERE o.id IS NULL で「注文行が無かった顧客」だけを残せます。マーケティング部門でよく使う定番パターンで、休眠顧客抽出やフォローアップ施策の対象選定に直結します。

代表例 2 — 売上ゼロも 0 円として集計

SQL クエリ

SELECT c.id, c.name, COALESCE(SUM(o.amount), 0) AS total FROM customers c LEFT JOIN orders o ON c.id = o.customer_id GROUP BY c.id, c.name;

注文がない顧客は SUM が NULL になるので、COALESCE で 0 に置き換えます。レポートが「未購入は空白」ではなく「未購入は ¥0」と表示されるようになり、見る側に親切です。

RIGHT OUTER JOIN

RIGHT JOINLEFT JOIN の左右を入れ替えただけです。可読性のため実務ではほとんど LEFT JOIN に書き換えて使います。

SQL クエリ

-- 同じ意味 SELECT ... FROM A RIGHT JOIN B ON ...; SELECT ... FROM B LEFT JOIN A ON ...;

複数テーブルを結合するときは「主軸となるテーブルを左に置き、LEFT JOIN で広げる」と読みやすくなります。RIGHT JOIN と LEFT JOIN を混ぜるとレビューしづらいので避けましょう。チーム開発では「LEFT に統一」をスタイルガイドにする会社も多いです。

落とし穴 — WHERE で OUTER の効果を消す

LEFT JOIN した後に WHERE で右テーブルの列を条件に使うと、その時点で右側 NULL の行が落ちて INNER JOIN と同じ結果になります。「未購入の顧客」を残したいなら、右テーブルの条件は ON 句側に書くか、WHERE o.col IS NULL の形で扱います。実務でよくバグの温床になるので、レビューのチェックポイントとして頭に入れておきましょう。

FULL OUTER JOIN について

両側を全件残したい場合は FULL OUTER JOIN を使いますが、MySQL / TiDB では非対応です。LEFT JOIN ... UNION ... RIGHT JOIN のように UNION で代替するか、PostgreSQL を使うときだけ書く、と覚えておけば十分です。

実例 — マスタとの差分チェック

SQL クエリ

-- 顧客マスタには登録あるが、注文履歴に 1 件もない顧客 SELECT c.id, c.name FROM customers c LEFT JOIN orders o ON c.id = o.customer_id WHERE o.id IS NULL ORDER BY c.id;

データ品質チェックや、マイグレーション後の取りこぼし確認でよく使う形です。LEFT JOIN + IS NULL の組み合わせを「差集合」として覚えておくと、いろんな場面で使い回せます。

まとめ

  • LEFT OUTER JOIN は左テーブルを全件残し、右にないものは NULL で埋める
  • RIGHT OUTER JOIN は左右が逆。実務では LEFT に統一すると読みやすい
  • WHERE で右テーブルの列を条件にすると OUTER の効果が消えるので注意
  • 「未購入顧客抽出」「ゼロ円表示」など実務で頻出するパターン
  • MySQL/TiDB は FULL OUTER 非対応なので UNION で代替
  • LEFT JOIN + IS NULL は「差集合」を表す定番テクニック

次のレッスン

次は 複数テーブルの結合 です。複数のテーブルを結合し、関連するデータを効率的に取得します。

事前確認 — 進む前に次の 3 つができることを確認しましょう。

  1. OUTER JOIN の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. OUTER JOIN とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン

テーブル構造

schema.sql

CREATE TABLE customers ( id INT PRIMARY KEY, name VARCHAR(30) ); CREATE TABLE orders ( id INT PRIMARY KEY, customer_id INT, amount INT ); INSERT INTO customers VALUES (1, '田中'), (2, '鈴木'), (3, '佐藤'), (4, '高橋'), (5, '山田'); INSERT INTO orders VALUES (1001, 1, 2000), (1002, 1, 3000), (1003, 3, 1500), (1004, 4, 5000), (1005, 4, 2500);

期待される出力

customer_idcustomer_nametotal_amount
1田中5000
2鈴木0
3佐藤1500
4高橋7500
5山田0

ヒント

query.sql
query.sql
学習モード
コードの実行結果
データベースを初期化中...