データベースの設計や簡単な抽出依頼をこなす際、気を抜いてると結合結果がどうなるか毎回忘れてしまい、調べなおす事が何回かあったので、ここにメモしておきます。
この記事の内容
- テーブルの結合を考えるときは、データの軸がどちらか意識する
- LEFT JOIN(LEFT OUTER JOIN)はデータの軸が結合時左側のテーブル
- RIGHT JOINはデータの軸が右側のテーブル
- INNER JOINは結合する両テーブルに一致するレコードのみ表示される
サンプルデータ
今回の例で使うデータは以下の通りです。
ユーザテーブル
+-----------+----------+--------------+
| ユーザID | 名前 | 都道府県CD |
+-----------+----------+--------------+
| 1 | 太郎 | 1 |
| 2 | 二郎 | 1 |
| 3 | 悠真 | 3 |
| 4 | 蓮 | 3 |
| 5 | 花子 | 4 |
| 6 | 悦子 | 4 |
| 7 | 咲良 | 6 |
| 8 | 結菜 | 7 |
+-----------+-------------------------+
都道府県マスタ
+-------------+----------------+
| 都道府県CD | 都道府県名 |
+-------------+----------------+
| 1 | 東京都 |
| 2 | 神奈川県 |
| 3 | 埼玉県 |
| 4 | 千葉県 |
| 5 | 茨城県 |
| 6 | 栃木県 |
+-------------+----------------+
テーブル結合の種類
LEFT JOIN(LEFT OUTER JOIN)
ポイントとしては、結合する際のデータの軸がどこにあるかを意識すると考えやすいと思います。ユーザテーブルに対して都道府県マスタをLEFT JOINする場合は、データの軸がユーザテーブル(結合した左側のテーブル)になります。
ユーザテーブルは全レコードが表示され、それに対して都道府県マスタの都道府県CDが紐づく場合に結合され、紐づかなければ表示すらされません。都道府県マスタにない都道府県CDがユーザテーブルに存在した場合はNULLとなります。
SELECT * FROM `ユーザテーブル` LEFT JOIN `都道府県マスタ` ON `ユーザテーブル`.`都道府県CD`= `都道府県マスタ`.`都道府県CD`;
+-------------+--------+----------------+----------------+-----------------+
| ユーザID | 名前 | 都道府県CD | 都道府県CD | 都道府県名 |
+-------------+--------+----------------+----------------+-----------------+
| 1 | 太郎 | 1 | 1 | 東京都 |
| 2 | 二郎 | 1 | 1 | 東京都 |
| 3 | 悠真 | 3 | 3 | 埼玉県 |
| 4 | 蓮 | 3 | 3 | 埼玉県 |
| 5 | 花子 | 4 | 4 | 千葉県 |
| 6 | 悦子 | 4 | 4 | 千葉県 |
| 7 | 咲良 | 6 | 6 | 栃木県 |
| 8 | 結菜 | 7 | NULL | NULL |
+-------------+--------+----------------+----------------+-----------------+
RIGHT JOIN
RIGHT JOINはLEFT JOINの時とは逆に、データの軸が都道府県マスタ(結合した右側のテーブル)となります。 下記の例では、都道府県マスタのデータは全て表示されていますが、紐づかないユーザテーブルのレコードは表示されません。
また、ユーザマスタには無い都道府県CDが都道府県マスタに存在する場合は、結合されるユーザテーブルのレコードが無いためNULLで表示されます。
SELECT * FROM `ユーザテーブル` RIGHT JOIN `都道府県マスタ` ON `ユーザテーブル`.`都道府県CD`= `都道府県マスタ`.`都道府県CD`;
+-------------+--------+----------------+----------------+-----------------+
| ユーザID | 名前 | 都道府県CD | 都道府県CD | 都道府県名 |
+-------------+--------+----------------+----------------+-----------------+
| 1 | 太郎 | 1 | 1 | 東京都 |
| 2 | 二郎 | 1 | 1 | 東京都 |
| 3 | 悠真 | 3 | 3 | 埼玉県 |
| 4 | 蓮 | 3 | 3 | 埼玉県 |
| 5 | 花子 | 4 | 4 | 千葉県 |
| 6 | 悦子 | 4 | 4 | 千葉県 |
| 7 | 咲良 | 6 | 6 | 栃木県 |
| NULL | NULL | NULL | 2 | 神奈川県 |
| NULL | NULL | NULL | 5 | 茨城県 |
+-------------+--------+----------------+----------------+-----------------+
INNER JOIN
INNER JOINでは、データの軸は結合する両方のテーブルとなります。そのため、都道府県CDがユーザテーブルと都道府県マスタの両方に存在するレコードしか表示されません。
SELECT * FROM `ユーザテーブル` INNER JOIN `都道府県マスタ` ON `ユーザテーブル`.`都道府県CD`= `都道府県マスタ`.`都道府県CD`;
+-------------+--------+----------------+----------------+-----------------+
| ユーザID | 名前 | 都道府県CD | 都道府県CD | 都道府県名 |
+-------------+--------+----------------+----------------+-----------------+
| 1 | 太郎 | 1 | 1 | 東京都 |
| 2 | 二郎 | 1 | 1 | 東京都 |
| 3 | 悠真 | 3 | 3 | 埼玉県 |
| 4 | 蓮 | 3 | 3 | 埼玉県 |
| 5 | 花子 | 4 | 4 | 千葉県 |
| 6 | 悦子 | 4 | 4 | 千葉県 |
| 7 | 咲良 | 6 | 6 | 栃木県 |
+-------------+--------+----------------+----------------+-----------------+