情弱エンジニアのなかのblog

一人前のエンジニアになる為のブログです

MySQLの外部結合の条件について

SQLの制作で結合を使うのですが外部結合を使う際の注意と仕様を今一度まとめたいと思います。

以下のようなテーブルがあると仮定いたします。

customersテーブル
     顧客名  
+---+-------+
|id |name   |
+---+-------+
|1  |yamada |
|2  |tanaka |
|3  |satou  |
+---+-------+


customer_historiesテーブル
      顧客id         媒体id
+---+------------+---------+
|id |customer_id |media_id |
+---+------------+---------+
|1  | 1          |1        |
|2  | 2          |1        |
|3  | 2          |3        |
+---+------------+---------+


mediaテーブル
     媒体名 
+---+-------+
|id |name   |
+---+-------+
|1  |aaa    |
|2  |bbb    |
|3  |ccc    |
+---+-------+

この時customersテーブルとmediaテーブルを結合したいときにJOINを使うのですが 全ての顧客データもしくは全ての媒体データを出力する必要がある場合は LEFT JOIN もしくは RIGHT JOIN を使うことになるのですが その場合customersテーブルかmediaテーブルのどちらかのデータしか全てを取得することが出来ません。

SQL文は以下のようになります。

customersをすべて取得

SELECT
    *
FROM
    customers
LEFT JOIN
    customer_histories
ON
    customer_histories.customer_id = customers.id
LEFT JOIN
    media
ON
    customer_histories.media_id = media.id

検索結果は以下になります。

     顧客名        顧客id         媒体id    媒体名  
+---+-------+---+------------+---------+---+-------+
|id |name   |id |customer_id |media_id |id |name   |
+---+-------+---+------------+---------+---+-------+
|1  |yamada |1  | 1          |1        |1  |aaa    |
|2  |tanaka |2  | 2          |1        |1  |aaa    |
|2  |tanaka |3  | 2          |3        |3  |ccc    |
|3  |satou  |   |            |         |   |       |
+---+-------+---+------------+---------+---+-------+

mediaテーブルをすべて取得

SELECT
    *
FROM
    media
LEFT JOIN
    customer_histories
ON
    customer_histories.media_id = media.id
LEFT JOIN
    customers
ON
    customer_histories.customer_id = customers.id

検索結果は以下になります。

     媒体名        顧客id       媒体id       顧客名  
+---+-------+---+------------+---------+---+-------+
|id |name   |id |customer_id |media_id |id |name   |
+---+-------+---+------------+---------+---+-------+
|1  |aaa    |1  | 1          |1        |1  |yamada |
|1  |aaa    |2  | 2          |1        |2  |tanaka |
|2  |bbb    |   |            |         |   |       |
|3  |ccc    |3  | 3          |3        |3  |satou  |
+---+-------+---+------------+---------+---+-------+

といった形になります。 必要なデータによって結合の順番やFROMに何を指定するかを変更する必要があります。