SQLのJOINについて
SQLのJOINは、複数のテーブルを結合して1つの結果セットを取得するための機能です。JOINを使用することで、関連するデータを効率的に取得することができます。
どのJOINがどんな結合を行うのかを忘れてしまいがちなので、整理してまとめておきます。
また、縦の結合を行うUNIONについても説明します。
JOINの種類
SQLのJOINには主に以下の種類があります。
- INNER JOIN(または単にJOIN)
- LEFT JOIN (または LEFT OUTER JOIN)
- RIGHT JOIN (または RIGHT OUTER JOIN)
- FULL JOIN (または FULL OUTER JOIN)
- CROSS JOIN(または単にCROSS JOIN)
INNER JOIN
INNER JOINは、両方のテーブルに共通するデータのみを結合して取得する方法です。例えば、以下のように使用します。
テーブルAの例
| ID | 名前 |
|---|---|
| 1 | 田中 |
| 2 | 鈴木 |
| 3 | 佐藤 |
| 4 | 高橋 |
テーブルBの例
| ID | 年齢 |
|---|---|
| 1 | 25 |
| 2 | 30 |
| 4 | 28 |
SELECT *
FROM テーブルA
INNER JOIN テーブルB
ON テーブルA.id = テーブルB.id;結果
| ID | 名前 | 年齢 |
|---|---|---|
| 1 | 田中 | 25 |
| 2 | 鈴木 | 30 |
| 4 | 高橋 | 28 |
図にまとめると以下のようになります(AI生成)
LEFT JOIN
LEFT JOINは、左側のテーブルのすべてのデータを取得して、右側のテーブルの一致するデータを結合する方法です。
左側のテーブルはFROM句で指定されるテーブルで、右側のテーブルはJOIN句で指定されるテーブルを指します。
例えば、以下のように使用します。
テーブルAの例
| ID | 名前 |
|---|---|
| 1 | 田中 |
| 2 | 鈴木 |
| 3 | 佐藤 |
| 4 | 高橋 |
テーブルBの例
| ID | 年齢 |
|---|---|
| 1 | 25 |
| 2 | 30 |
| 4 | 28 |
SELECT テーブルA.id, テーブルA.名前, テーブルB.年齢
FROM テーブルA
LEFT JOIN テーブルB
ON テーブルA.id = テーブルB.id;※SELECT *とした場合、テーブルAのID,名前,テーブルBのID,年齢の順で取得されますが、テーブルBのIDがNULLとなり分かりにくくなるため、上のSQLでは必要なカラムのみを指定しています。
結果
| ID | 名前 | 年齢 |
|---|---|---|
| 1 | 田中 | 25 |
| 2 | 鈴木 | 30 |
| 3 | 佐藤 | NULL |
| 4 | 高橋 | 28 |
図にまとめると以下のようになります(AI生成)
RIGHT JOIN
RIGHT JOINは、右側のテーブルのすべてのデータを取得して、左側のテーブルの一致するデータを結合する方法です。
右側のテーブルはJOIN句で指定されるテーブルで、左側のテーブルはFROM句で指定されるテーブルを指します。
例えば、以下のように使用します。
テーブルAの例
| ID | 名前 |
|---|---|
| 1 | 田中 |
| 2 | 鈴木 |
| 3 | 佐藤 |
| 4 | 高橋 |
テーブルBの例
| ID | 年齢 |
|---|---|
| 1 | 25 |
| 2 | 30 |
| 4 | 28 |
| 5 | 22 |
SELECT テーブルA.id, テーブルA.名前, テーブルB.年齢
FROM テーブルA
RIGHT JOIN テーブルB
ON テーブルA.id = テーブルB.id;結果
| ID | 名前 | 年齢 |
|---|---|---|
| 1 | 田中 | 25 |
| 2 | 鈴木 | 30 |
| 4 | 高橋 | 28 |
| NULL | NULL | 22 |
図にまとめると以下のようになります(AI生成)
LEFT JOINとRIGHT JOINの違い
FROM テーブルA
LEFT JOIN テーブルBと
FROM テーブルB
RIGHT JOIN テーブルAは結果的に同じになることから、LEFT JOIN,RIGHT JOINはお互いに置き換えて使用することができます。
ですが、一般的にはLEFT JOINを使用することが多いです。LEFT JOINの方が直感的に理解しやすく、可読性も高いためです。
調べた限り、RIGHT JOINは実務でほとんど見たことがないといった意見が多くみられました。
例えば長いSQLで運用していて、途中でほしい結果が変わった場合のようなユースケースでは、SQLをがらっと書き直すのではなく、LEFT JOINからRIGHT JOINに書き直すことがあるようです。
AI時代の今では上記のようなユースケースでも、LEFT JOINのままでリファクタリングすることが可能ではありますが、、。
FULL JOIN
FULL JOINは、両方のテーブルのすべてのデータを取得して、共通するデータを結合する方法です。
一致しないデータについてはNULLが入ります。
例えば、以下のように使用します。
テーブルAの例
| ID | 名前 |
|---|---|
| 1 | 田中 |
| 2 | 鈴木 |
| 3 | 佐藤 |
| 4 | 高橋 |
テーブルBの例
| ID | 年齢 |
|---|---|
| 1 | 25 |
| 2 | 30 |
| 4 | 28 |
| 5 | 22 |
SELECT テーブルA.id, テーブルA.名前, テーブルB.年齢
FROM テーブルA
FULL JOIN テーブルB
ON テーブルA.id = テーブルB.id;結果
| ID | 名前 | 年齢 |
|---|---|---|
| 1 | 田中 | 25 |
| 2 | 鈴木 | 30 |
| 3 | 佐藤 | NULL |
| 4 | 高橋 | 28 |
| NULL | NULL | 22 |
片方のテーブルにしか存在しないデータも漏れなく取得されるのがFULL JOINの特徴です。
図にまとめると以下のようになります(AI生成)
注意点としては、FULL JOINはMySQLなど一部のデータベースではサポートされていない場合があることです。
その場合は、LEFT JOINとRIGHT JOINで出した結果をUNIONで結合することで、FULL JOINと同様の結果を得ることができます。
例えば、以下のようにLEFT JOINとRIGHT JOINをUNIONで結合することで、FULL JOINと同様の結果を得ることができます。
SELECT テーブルA.id, テーブルA.名前, テーブルB.年齢
FROM テーブルA
LEFT JOIN テーブルB
ON テーブルA.id = テーブルB.id
UNION
SELECT テーブルA.id, テーブルA.名前, テーブルB.年齢
FROM テーブルA
RIGHT JOIN テーブルB
ON テーブルA.id = テーブルB.id;UNIONとは
UNIONは、複数のSELECT文の結果を結合して1つの結果セットとして返すSQLの構文です。
JOINが「横の結合」を行うのに対して、UNIONは「縦の結合」を行うと考えると理解しやすいです。
重複する行は自動的に削除されます。重複を残したい場合は、UNION ALLを使用します。
UNION と UNION ALLの図は以下のようになります。
CROSS JOIN
CROSS JOINは、両方のテーブルのすべての組み合わせを取得する結合方法です。
リレーションは関係なく、すべての組み合わせが取得されます。
例えば、以下のように使用します。
テーブルAの例
| ID | 名前 |
|---|---|
| 1 | 田中 |
| 2 | 鈴木 |
テーブルBの例
| ID | 年齢 |
|---|---|
| 1 | 25 |
| 2 | 30 |
SELECT テーブルA.id, テーブルA.名前, テーブルB.年齢
FROM テーブルA
CROSS JOIN テーブルB;結果
| ID | 名前 | 年齢 |
|---|---|---|
| 1 | 田中 | 25 |
| 1 | 田中 | 30 |
| 2 | 鈴木 | 25 |
| 2 | 鈴木 | 30 |
図にまとめると以下のようになります(AI生成)
理解度チェック(AI生成)
以下の4択問題で、JOINとUNIONの理解度をチェックしてみましょう。答えは折りたたまれているので、クリックして確認してください。
Q1. INNER JOINの説明として正しいものはどれか?
- 両方のテーブルのすべてのデータを取得する
- 左側のテーブルのすべてのデータを取得する
- 両方のテーブルに共通するデータのみを取得する
- 両方のテーブルのすべての組み合わせを取得する
答えを見る
正解: 3. 両方のテーブルに共通するデータのみを取得する INNER JOINは、結合条件に一致するデータ、つまり両方のテーブルに共通するデータのみを結合して取得する方法です。
Q2. 記事中で説明されている、LEFT JOINとRIGHT JOINの関係として正しいものはどれか?
- FROM句とJOIN句のテーブルを入れ替えれば、互いに置き換えて同じ結果を得られる
- RIGHT JOINはLEFT JOINより新しい構文であり、原則RIGHT JOINを使うべきである
- LEFT JOINとRIGHT JOINは結合条件の書き方が異なり、置き換えることはできない
- RIGHT JOINはNULLを含む結果を返さない
答えを見る
正解: 1. FROM句とJOIN句のテーブルを入れ替えれば、互いに置き換えて同じ結果を得られる
FROM テーブルA LEFT JOIN テーブルBとFROM テーブルB RIGHT JOIN テーブルAは結果的に同じになるため、互いに置き換えて使用できます。ただし、一般的にはLEFT JOINの方が直感的で可読性が高いため多く使われます。
Q3. FULL JOINの特徴として正しいものはどれか?
- 両方のテーブルに共通するデータのみを取得する
- 片方のテーブルにしか存在しないデータも漏れなく取得され、一致しない部分にはNULLが入る
- すべてのデータベースで標準的にサポートされている
- 結合条件を指定せずに使用する
答えを見る
正解: 2. 片方のテーブルにしか存在しないデータも漏れなく取得され、一致しない部分にはNULLが入る FULL JOINは両方のテーブルのすべてのデータを取得し、一致しないデータについてはNULLが入ります。なお、MySQLなど一部のデータベースではFULL JOINがサポートされておらず、その場合はLEFT JOINとRIGHT JOINの結果をUNIONで結合することで同様の結果を得られます。
Q4. CROSS JOINの説明として正しいものはどれか?
- 結合条件(ON句)に基づいて一致する行のみを結合する
- リレーションに関係なく、両方のテーブルのすべての組み合わせを取得する
- 片方のテーブルのデータのみを重複なく取得する
- 複数のSELECT文の結果を縦に結合する
答えを見る
正解: 2. リレーションに関係なく、両方のテーブルのすべての組み合わせを取得する CROSS JOINはリレーションに関係なく、両方のテーブルのすべての組み合わせ(直積)を取得する結合方法です。
Q5. JOINとUNIONの違いとして、記事の内容と合致するものはどれか?
- JOINは「縦の結合」、UNIONは「横の結合」を行う
- JOINは「横の結合」、UNIONは「縦の結合」を行う
- JOINとUNIONはどちらも同じ処理を行い、書き方が異なるだけである
- UNIONは常に重複行を残す
答えを見る
正解: 2. JOINは「横の結合」、UNIONは「縦の結合」を行う JOINが複数のテーブルをカラム方向(横)に結合するのに対し、UNIONは複数のSELECT文の結果を行方向(縦)に結合します。また、UNIONは重複する行を自動的に削除しますが、重複を残したい場合は
UNION ALLを使用します。