MySQLでの3つ以上のテーブル結合について

バックエンド
date 2014.04.17 tag MySQL

MySQLでのテーブルの結合について。
3つ以上のテーブルを結合する時にどのような挙動になるのか人にうまく説明できなかったので、簡単なサンプルを作成して確認してみました。

実践用テーブル

サンプルとしてはあまり良くないかも知れませんが、とりあえず結合用に下記の3つの結合フィールドを持つテーブルとデータを用意します。

MySQLテーブルの作成

mysql> CREATE TABLE one(id int(10));
mysql> CREATE TABLE two(id int(10));
mysql> CREATE TABLE three(id int(10));

MySQL格納データ

mysql> SELECT * FROM one;
+------+
| id   |
+------+
|    1 |
|    3 |
|    5 |
+------+
3 rows in set (0.01 sec)

mysql> SELECT * FROM two;
+------+
| id   |
+------+
|    5 |
|    4 |
+------+
2 rows in set (0.00 sec)

mysql> SELECT * FROM three;
Empty set (0.00 sec)

3つのテーブルの結合

全く具体的なデータが入っていないテーブルですが結合してみます。「one.id=two.id」で内部結合してから「two.id=three.id」で外部結合(LEFT JOIN)します。

内部結合

まずは「one」と「two」の内部結合から。
内部結合はJOINまたはWHERE句で同値結合のいずれかで実現しますが、ここではJOINで「one.id=two.id」の条件で結合させます。双方のテーブルに存在するid=5のレコードのみ結合され、結果的に1件のレコードになることを確認できます。

MySQL内部結合

mysql> SELECT one.id AS one_id, two.id AS two_id FROM one JOIN two ON (one.id=two.id);
+--------+--------+
| one_id | two_id |
+--------+--------+
|      5 |      5 |
+--------+--------+
1 row in set (0.00 sec)

外部結合(LEFT JOIN)

内部結合後に「two.id=three.id」という条件で外部結合を加えてみます。
抽出されるのは1件で、この結果から分かることですがLEFT JOINは「LEFT JOINの左側」に存在する1つのテーブル(レコードの集まり)を基準に結合を行います。つまり先に内部結合を行った1件のテーブルに対して結合しています。

MySQL外部結合の追加

mysql> SELECT one.id AS one_id, two.id AS two_id, three.id AS three_id FROM one JOIN two ON (one.id=two.id) LEFT JOIN three ON (two.id=three.id);
+--------+--------+----------+
| one_id | two_id | three_id |
+--------+--------+----------+
|      5 |      5 |     NULL |
+--------+--------+----------+
1 row in set (0.00 sec)

ONで指定しているのはあくまで結合条件なので、twoを基準に左結合を行っている訳ではありません。

まとめ

複数個のテーブル結合は「(a + b) + c」のように結合したテーブルをさらに結合していくという見方をしていけば混乱しないです。