FULL OUTER JOIN
| 対応: | SQL-92(1992) |
|---|
両テーブルの全行を保持して結合する方法です。どちらかのテーブルにしか存在しない行も結果に含まれます。
構文
『FULL OUTER JOIN』(PostgreSQL で使用可能)。
SELECT 列名 FROM テーブル1 FULL OUTER JOIN テーブル2 ON テーブル1.結合列 = テーブル2.結合列;
MySQL では『FULL OUTER JOIN』が未対応のため、『UNION』で代替します。
SELECT 列名 FROM テーブル1 LEFT JOIN テーブル2 ON テーブル1.結合列 = テーブル2.結合列 UNION SELECT 列名 FROM テーブル1 RIGHT JOIN テーブル2 ON テーブル1.結合列 = テーブル2.結合列;
結合種別の比較
| 結合種別 | 左テーブルのみ | 両方一致 | 右テーブルのみ |
|---|---|---|---|
| INNER JOIN | 含まない。 | 含む。 | 含まない。 |
| LEFT JOIN | 含む(右側はNULL)。 | 含む。 | 含まない。 |
| RIGHT JOIN | 含まない。 | 含む。 | 含む(左側はNULL)。 |
| FULL OUTER JOIN | 含む(右側はNULL)。 | 含む。 | 含む(左側はNULL)。 |
サンプルコード
以下の『employees』テーブルと『departments』テーブルを例に説明します。
社員と部署を結合します。部署未設定の社員も、社員のいない部署も含みます(PostgreSQL)。
sample_full_outer_join.sql
SELECT e.name, d.department_name FROM employees AS e FULL OUTER JOIN departments AS d ON e.department_id = d.id;
+------------------+------------------+ | name | department_name | +------------------+------------------+ | 八神庵 | 八神流古武術 | | 草薙京 | 草薙流古武術 | | テリー・ボガード | NULL | | NULL | サウスタウン | +------------------+------------------+ 4 rows in set
MySQL での代替:『LEFT JOIN』と『RIGHT JOIN』を『UNION』で結合します。
sample_full_outer_join.sql
SELECT e.name, d.department_name FROM employees AS e LEFT JOIN departments AS d ON e.department_id = d.id UNION SELECT e.name, d.department_name FROM employees AS e RIGHT JOIN departments AS d ON e.department_id = d.id;
+------------------+------------------+ | name | department_name | +------------------+------------------+ | 八神庵 | 八神流古武術 | | 草薙京 | 草薙流古武術 | | テリー・ボガード | NULL | | NULL | サウスタウン | +------------------+------------------+ 4 rows in set
どちらかのテーブルにしか存在しない行(非一致行)のみを取得します(PostgreSQL)。
sample_full_outer_join.sql
SELECT e.name, d.department_name FROM employees AS e FULL OUTER JOIN departments AS d ON e.department_id = d.id WHERE e.id IS NULL OR d.id IS NULL;
+------------------+-----------------+ | name | department_name | +------------------+-----------------+ | テリー・ボガード | NULL | | NULL | サウスタウン | +------------------+-----------------+ 2 rows in set
データベース別の書き方
PostgreSQL は『FULL OUTER JOIN』をそのまま使用できます。
-- PostgreSQL SELECT e.name, d.department_name FROM employees AS e FULL OUTER JOIN departments AS d ON e.department_id = d.id;
MySQL は『FULL OUTER JOIN』に対応していません。『LEFT JOIN』と『RIGHT JOIN』を『UNION』で組み合わせて代替します。
-- MySQL(UNION で代替) SELECT e.name, d.department_name FROM employees AS e LEFT JOIN departments AS d ON e.department_id = d.id UNION SELECT e.name, d.department_name FROM employees AS e RIGHT JOIN departments AS d ON e.department_id = d.id;
SQLite も『FULL OUTER JOIN』に対応していません(3.39.0 以降で対応)。古いバージョンでは MySQL と同様に『LEFT JOIN』の『UNION』で代替してください。ただし SQLite は『RIGHT JOIN』も 3.39.0 以降のため、それ以前のバージョンではテーブルの順序を入れ替えた2つの『LEFT JOIN』を『UNION』します。
-- SQLite(3.39.0 未満)での代替方法 SELECT e.name, d.department_name FROM employees AS e LEFT JOIN departments AS d ON e.department_id = d.id UNION SELECT e.name, d.department_name FROM departments AS d LEFT JOIN employees AS e ON e.department_id = d.id;
概要
『FULL OUTER JOIN』は両テーブルのすべての行を保持する結合で、データ整合性の確認(孤立レコードの検出)や2つのデータセットの差分確認などに使用されます。
MySQLはFULL OUTER JOINに対応していません。MySQLで同等の結果を得るには、LEFT JOINとRIGHT JOINを『UNION』(重複除去あり)または『UNION ALL』(重複保持)で組み合わせる必要があります。UNION ALLを使う場合は手動で重複を除去するか、UNION(重複除去)を使用してください。
各テーブルに対応行がない部分はNULLになります。『IS NULL / IS NOT NULL』と組み合わせることで、どちらかのテーブルにしか存在しない行を特定できます。JOINの種類については『INNER JOIN』・『LEFT JOIN / RIGHT JOIN』も合わせて参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。