この記事では、データベースの結合の種類を理解する。
それぞれどういう結合かを理解するためなので、具体的なSQL文までは説明しない。
扱うサンプルデータ
このサンプルデータのポイントは2つ。
- 田中さんと佐藤さんは同じ部署
- 人事の部署には誰も所属していない
社員ID | 社員名 | 部署ID |
001 | 高橋 | A |
002 | 田中 | B |
003 | 佐藤 | B |
部署ID | 部署名 |
A | 営業 |
B | 開発 |
C | 人事 |
クロス結合
クロス結合は、テーブル同士を脳死で全部組み合わせる結合方法。
クロス結合を行うと、テーブルのレコード数を単純に掛け算した数のデータが取得できる。
3(社員テーブル) × 3(部署テーブル) = 9レコード
社員ID | 社員名 | (社員テーブルの)部署ID | (部署テーブルの)部署ID | 部署名 |
001 | 高橋 | A | A | 営業 |
001 | 高橋 | A | B | 開発 |
001 | 高橋 | A | C | 人事 |
002 | 田中 | B | A | 営業 |
002 | 田中 | B | B | 開発 |
002 | 田中 | B | C | 人事 |
003 | 佐藤 | C | A | 営業 |
003 | 佐藤 | C | B | 開発 |
003 | 佐藤 | C | C | 人事 |
実務で使う機会はほとんどなく、実際に使われていたとしたら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 | 人事 | null | null |
内部結合では、人事に所属している社員が存在していないため
実行結果に出力されることはなかったが、
外部結合では「部署テーブルを基準として結合する」という方法を取ったため、
所属している社員がいない場合はnullで補完される。
実務で使う場合は、
「部署テーブル一覧に処理を行いたい。部署に誰も所属していない場合は〇〇したい」
みたいなケースが考えられる。
内部結合してしまうと、部署「人事」に対する処理が漏れてしまうためだ。
補足:社員テーブルを基準テーブルとした場合
内部結合との差分が分かりやすくするため部署テーブルを基準として話をしたが、
社員テーブルを基準とした外部結合を行う場合は以下の通りになる。
社員ID | 社員名 | 部署ID | 部署名 |
001 | 高橋 | A | 営業 |
002 | 田中 | B | 開発 |
003 | 佐藤 | B | 開発 |
このデータでは社員は必ず部署に所属しているため、nullで補完されることなく
結果的には内部結合と同じ結果になる。
外部結合の種類
よく利用する外部結合の種類としては2種類あるが、
「SQLのどこに書いたテーブルを基準にするか」が違うだけなので、
以下のようにざっくり覚えておくと良い。
- 左外部結合(left outer join):左側(fromの方)に書いたテーブルを基準にする
- 右外部結合(right outer join):右側(outer joinの後)に書いたテーブルを基準とする
個人的には左外部結合の方が直感的だと思っているので、
右外部結合でSQLを記述したことはほとんどない。
まとめ
- クロス結合:ほぼ使わない、知識として知っておく程度で良い
- 内部結合:一番よく利用するシンプルな結合方法
- 外部結合:内部結合に似ているが、どちらかに存在しないレコードはnullで補完される