【DB】テーブル結合方法の種類を理解する(内部結合、外部結合、クロス結合)

サーバーのイメージ画像 データベース

この記事では、データベースの結合の種類を理解する。

それぞれどういう結合かを理解するためなので、具体的なSQL文までは説明しない。

扱うサンプルデータ

このサンプルデータのポイントは2つ。

  • 田中さんと佐藤さんは同じ部署
  • 人事の部署には誰も所属していない
社員ID社員名部署ID
001高橋A
002田中B
003佐藤B
社員テーブル
部署ID部署名
A営業
B開発
C人事
部署テーブル

クロス結合

クロス結合は、テーブル同士を脳死で全部組み合わせる結合方法。

クロス結合を行うと、テーブルのレコード数を単純に掛け算した数のデータが取得できる。

3(社員テーブル) × 3(部署テーブル) = 9レコード
社員ID社員名(社員テーブルの)部署ID(部署テーブルの)部署ID部署名
001高橋AA営業
001高橋AB開発
001高橋AC人事
002田中BA営業
002田中BB開発
002田中BC人事
003佐藤CA営業
003佐藤CB開発
003佐藤CC人事
社員テーブルと部署テーブルのクロス結合

実務で使う機会はほとんどなく、実際に使われていたとしたらSQLを見直した方が良い。
使われない理由は2点。

  • この結果を使いたいようなケースはかなり稀なケース
  • パフォーマンスがめちゃくちゃ悪い

これから紹介する内部結合と外部結合は、このクロス結合の部分集合になる。

内部結合(inner join)

内部結合は、実務で最もよく使われる結合方法。

簡単に言うと、「どちらのテーブルにも存在するデータを、何らかのキーを決めて繋ぐ」結合方法。

サンプルデータでは「社員一覧と、その社員が所属している部署名の組み合わせ一覧を取得したい」
というような時に利用する。

社員ID社員名部署ID部署名
001高橋A営業
002田中B開発
003佐藤B開発
社員テーブルと部署テーブルの内部結合

サンプルデータのテーブルは正規化されているため、
「高橋さんの部署名を取得したい」という場合、社員テーブルだけを見てしまうと
部署IDは分かるけど部署名は分からない、ということになる。

そのため、「部署IDをキーに、社員テーブルと部署テーブルを結合して部署名を補完する」という方法を取るのが内部結合の主な目的である。

外部結合(outer join)

外部結合は、簡単に説明すると「基準となるテーブルを一つ決めて、そのテーブルを補完するようにもう一つのテーブルを繋ぐ」方法。

内部結合と大きく異なる点は、「null埋めが行われる」という点である。

部署テーブルを基準となるテーブルとして考えて外部結合を行うと、以下のイメージになる。

部署ID部署名社員ID社員名
A営業001高橋
B開発002田中
B開発003佐藤
C人事nullnull
部署テーブルを基準として社員テーブルと外部結合する

内部結合では、人事に所属している社員が存在していないため
実行結果に出力されることはなかったが、
外部結合では「部署テーブルを基準として結合する」という方法を取ったため、
所属している社員がいない場合はnullで補完される。

実務で使う場合は、
「部署テーブル一覧に処理を行いたい。部署に誰も所属していない場合は〇〇したい」
みたいなケースが考えられる。

内部結合してしまうと、部署「人事」に対する処理が漏れてしまうためだ。

補足:社員テーブルを基準テーブルとした場合

内部結合との差分が分かりやすくするため部署テーブルを基準として話をしたが、
社員テーブルを基準とした外部結合を行う場合は以下の通りになる。

社員ID社員名部署ID部署名
001高橋A営業
002田中B開発
003佐藤B開発
社員テーブルを基準として部署テーブルと外部結合する

このデータでは社員は必ず部署に所属しているため、nullで補完されることなく
結果的には内部結合と同じ結果になる。

外部結合の種類

よく利用する外部結合の種類としては2種類あるが、
「SQLのどこに書いたテーブルを基準にするか」が違うだけなので、
以下のようにざっくり覚えておくと良い。

  • 左外部結合(left outer join):左側(fromの方)に書いたテーブルを基準にする
  • 右外部結合(right outer join):右側(outer joinの後)に書いたテーブルを基準とする

個人的には左外部結合の方が直感的だと思っているので、
右外部結合でSQLを記述したことはほとんどない。

まとめ

  • クロス結合:ほぼ使わない、知識として知っておく程度で良い
  • 内部結合:一番よく利用するシンプルな結合方法
  • 外部結合:内部結合に似ているが、どちらかに存在しないレコードはnullで補完される
タイトルとURLをコピーしました