🔛

テーブル結合入門(SQL / JOIN)

2024/03/16に公開

SQL における結合を個人的にまとめてみました。
以下の内容を記載してます。

  • そもそも結合(JOIN)とは
  • 結合(JOIN)の種類
  • 結合(JOIN)の仕方

そもそも JOIN とは

JOIN はクエリにおける演算のことで、複数テーブル同士を横に結合してデータを取得する方法です。

データを取得してくる時、欲しいデータが複数のテーブルに分散されていることが頻繁にあります。
その時に JOIN テーブル同士を結合して取得をすると一回のクエリでまとめて取ってこれるので便利です。


結合(JOIN)のイメージ

結合の種類

結合には用途に応じていくつか種類がありますが、以下 3 種類を覚えていれば業務としては問題ないのかなと思います。

  • クロス結合(CROSS JOIN)
  • 内部結合(INNER JOIN)
  • 外部結合(OUTER JOIN)

クロス結合(CROSS JOIN)

クロス結合は全ての組み合わせを作成するものです。
実際は以下の図のようになります。

■ クエリ

クロス結合をするときはCROSS JOINを使用します。
CROSS JOINONで条件を指定しないので、以下のような簡易的な命令になります。
ONも記述自体はできますが、内部結合と同じ結果になってしまいます。

SELECT * FROM table_a CROSS JOIN table_b;

内部結合(INNER JOIN)

内部結合とは、テーブル間で関連性のある要素同士を組み合わせて取得をするものです。
テーブル同士を組み合わせて表示するのに一番適しているので、業務で使う可能性が一番高いのが内部結合です。

■ クエリ

内部結合はINNER JOINを使用しONでどのカラムを関連づけるか指定します。
上記の画像のように、table_a.b_join_idtable_b.idを結合する場合は以下のクエリになります。

SELECT
    *
FROM
    table_a
    INNER JOIN
        table_b
    ON  table_a.b_join_id = table_b.id
;

外部結合(OUTER JOIN)

内部結合は共通している要素を持っているレコードだけ取得をしていましたが、外部結合は関連性が無い場合でも取得することができます。
内部結合は内側で合体するイメージですが、外部結合は片方のテーブルに対して外からテーブルをくっつけたようなイメージです。

どちら側に結合をするかで記述が異なり、以下の外部結合を主に使用します。

  • 左外部結合(LEFT OUTER JOIN / LEFT JOIN)
  • 右外部結合(RIGHT OUTER JOIN / RIGHT JOIN)

それぞれ画像があった方がわかりやすいと思うので、以下にそれぞれ記載してます。

左外部結合(LEFT OUTER JOIN / LEFT JOIN)

右外部結合(RIGHT OUTER JOIN / RIGHT JOIN)

クエリは内部結合とほぼ変わらず、INNERの箇所をLEFT OUTERにするか、RIGHT OUTERにするかだけです。

-- 左外部結合(LEFT OUTER JOIN)
SELECT
    *
FROM
    table_a
    LEFT OUTER JOIN
        table_b
    ON  table_a.b_join_id = table_b.id
;

-- 右外部結合(RIGHT OUTER JOIN)
SELECT
    *
FROM
    table_a
    RIGHT OUTER JOIN
        table_b
    ON  table_a.b_join_id = table_b.id
;

※完全外部結合(FULL OUTER JOIN)

右外部結合と左外部結合を合わせた形として完全外部結合というものがありますが、MySQL8.0 では使用できないのと、一般的な業務としてはほぼ使用しないと思うのでここでは省略します

それぞれの結合をベン図で表してみる

自分が JOIN を最初に勉強したとき、ベン図で書いていた本がとてもわかりやすかったので以下にも記載しておきます。

その他結合に関する補足

  • 結合には 2 つのテーブルより多くのテーブルを結合することができる
  • JOINを使用せず、SELECT句だけで結合クエリを書くことができるが、古い構文なのと、結合のクエリかどうかわからないので、SELECT句だけの結合クエリは特段理由がなければ書かない
  • ONで指定する結合カラムにNULLが入っている場合は意図しない挙動になる可能性がある
  • JOINする前に条件絞りこみを行ってから結合した方がパフォーマンスが良くなることがある。(JOINの方がWHEREよりも先に実行されるので)
  • 結合カラムのインデックスもパフォーマンスに影響が出るので、結合も意識したインデックス設計をすると良い

参考

Discussion