SQLのJOIN(結合)とは ― 種類と使い分け
SQLの
JOINとは、2つ以上の表を共通の列でつなぐ操作
SQLのJOIN(結合)とは、2つ以上の表を、共通の列の値をもとにつなぐ操作です。RDB(リレーショナルデータベース)はデータを複数の表に分けて持ちます。そのため、顧客と注文のように分かれた表から情報をまとめて取り出すときに、JOINを使います。
例えば、顧客テーブルと注文テーブルがあるとします。注文テーブルは、どの顧客の注文かを外部キーの顧客IDで示します。顧客の氏名とその人の注文を同時に見たいときは、2つの表を顧客IDでJOINします。
JOINには複数の種類があり、一致しない行(相手が見つからない行)を結果に含めるかどうかが違います。書き方は、SELECT文のSELECT・FROM・WHEREに、JOINの指定が1つ加わる形です。
JOINは行を横につなぎ、列を増やします。同じ列を持つ2つの結果を縦につないで行を増やしたいときは、UNIONを使います。
INNER・LEFT・RIGHT・FULLの4種類は、残す行の範囲が違う
代表的なJOINには、INNER JOIN・LEFT JOIN・RIGHT JOIN・FULL JOINの4種類があります。違いは、どちらの表の行をどこまで残すかです。
| 種類 | 別の | 結果に |
|---|---|---|
| INNER JOIN | INNERを省いてJOINとだけ書いても同じ | 両方の表で顧客IDが一致する行だけ |
| LEFT JOIN | LEFT OUTER JOINとも書く | 左側(FROMの表)の行は全部。一致しない分は右側が空になる |
| RIGHT JOIN | RIGHT OUTER JOINとも書く | 右側(JOINの表)の行は全部。一致しない分は左側が空になる |
| FULL JOIN | FULL OUTER JOINとも書く | 両方の表の行が全部。一致しない分はどちらかが空になる |
INNER JOINは、両方の表で値が一致する行だけを残し、一致しない行は結果から消えます。この結合を内部結合と呼びます。
LEFT JOINとRIGHT JOINは、一方の表の行を必ず残します。LEFT JOINはFROMの直後に書いた表(左側)、RIGHT JOINはJOINの直後に書いた表(右側)の行を全部残します。一致する相手がいない行は、もう一方の表の列を空(NULL)にして結果に残ります。この空の列をIS NULLで探す書き方は、SQLのNULLの記事で説明しています。
FULL JOINは、両方の表の行を全部残します。一致する相手がいない行は、どちらの表にあっても、空の列を付けて結果に加わります。LEFT JOIN・RIGHT JOIN・FULL JOINのように、一致しない行も残す結合を外部結合と呼びます。
RIGHT JOINとFULL JOINは、DBMSによって使えない場合があります。MySQLは、FULL JOINに対応していません。SQLiteは、2022年公開のバージョン3.39.0でRIGHT JOINとFULL JOINに対応しました。PostgreSQLやSQL Serverでは、4種類とも使えます。なお、RIGHT JOINで取り出す行は、2つの表の順番を入れ替えればLEFT JOINでも取り出せます。
JOINの種類を選んで、結果の行を見る
次の図でJOINの種類を選ぶと、SQL文と結果の表が変わります。どの種類も同じ顧客テーブルと注文テーブルを使います。図は実際のデータベースには接続しておらず、結果はあらかじめ計算した固定の値です。顧客104には注文が無く、注文5005の顧客ID106は顧客テーブルにありません。この2行の扱いが、種類ごとに変わります。
顧客テーブル
| 顧客ID | 氏名 |
|---|---|
| 101 | 田中美咲 |
| 102 | 佐藤健太 |
| 103 | 鈴木大輔 |
| 104 | 高橋愛 |
注文テーブル
| 注文ID | 顧客ID | 商品 |
|---|---|---|
| 5001 | 101 | ノートPC |
| 5002 | 101 | モニター |
| 5003 | 102 | マウス |
| 5004 | 103 | キーボード |
| 5005 | 106 | デスク |
色のついた行(顧客104・注文5005)は、もう一方の表に一致する顧客IDが無い行です。
SELECT c.顧客ID, c.氏名, o.注文ID, o.顧客ID AS 注文側顧客ID, o.商品
FROM 顧客 AS c
INNER JOIN 注文 AS o ON c.顧客ID = o.顧客ID;両方の表で顧客IDが一致する行だけが残ります。注文が無い顧客104と、顧客がいない注文5005はどちらも消えます。
| 顧客ID | 氏名 | 注文ID | 注文側顧客ID | 商品 |
|---|---|---|---|---|
| 101 | 田中美咲 | 5001 | 101 | ノートPC |
| 101 | 田中美咲 | 5002 | 101 | モニター |
| 102 | 佐藤健太 | 5003 | 102 | マウス |
| 103 | 鈴木大輔 | 5004 | 103 | キーボード |
SELECT c.顧客ID, c.氏名, o.注文ID, o.顧客ID AS 注文側顧客ID, o.商品
FROM 顧客 AS c
LEFT JOIN 注文 AS o ON c.顧客ID = o.顧客ID;左側(FROMの直後)の顧客の行は全て残ります。注文が無い顧客104も、注文側の列を空にして1行として出ます。注文5005は消えます。
| 顧客ID | 氏名 | 注文ID | 注文側顧客ID | 商品 |
|---|---|---|---|---|
| 101 | 田中美咲 | 5001 | 101 | ノートPC |
| 101 | 田中美咲 | 5002 | 101 | モニター |
| 102 | 佐藤健太 | 5003 | 102 | マウス |
| 103 | 鈴木大輔 | 5004 | 103 | キーボード |
| 104 | 高橋愛 | (空) | (空) | (空) |
SELECT c.顧客ID, c.氏名, o.注文ID, o.顧客ID AS 注文側顧客ID, o.商品
FROM 顧客 AS c
RIGHT JOIN 注文 AS o ON c.顧客ID = o.顧客ID;右側(JOINの直後)の注文の行は全て残ります。顧客がいない注文5005も、顧客側の列を空にして1行として出ます。顧客104は消えます。
| 顧客ID | 氏名 | 注文ID | 注文側顧客ID | 商品 |
|---|---|---|---|---|
| 101 | 田中美咲 | 5001 | 101 | ノートPC |
| 101 | 田中美咲 | 5002 | 101 | モニター |
| 102 | 佐藤健太 | 5003 | 102 | マウス |
| 103 | 鈴木大輔 | 5004 | 103 | キーボード |
| (空) | (空) | 5005 | 106 | デスク |
SELECT c.顧客ID, c.氏名, o.注文ID, o.顧客ID AS 注文側顧客ID, o.商品
FROM 顧客 AS c
FULL JOIN 注文 AS o ON c.顧客ID = o.顧客ID;両方の表の行が全て残ります。注文が無い顧客104と、顧客がいない注文5005のどちらも、空の列を伴って1行ずつ出ます。
| 顧客ID | 氏名 | 注文ID | 注文側顧客ID | 商品 |
|---|---|---|---|---|
| 101 | 田中美咲 | 5001 | 101 | ノートPC |
| 101 | 田中美咲 | 5002 | 101 | モニター |
| 102 | 佐藤健太 | 5003 | 102 | マウス |
| 103 | 鈴木大輔 | 5004 | 103 | キーボード |
| 104 | 高橋愛 | (空) | (空) | (空) |
| (空) | (空) | 5005 | 106 | デスク |
参考にした資料
- PostgreSQL公式ドキュメント「Table Expressions」(INNER・LEFT・RIGHT・FULL JOINの構文と、一致しない行の扱いの違い)
- MySQL 8.4 Reference Manual「JOIN Clause」(MySQLで使える結合の種類。FULL JOINが無いこと)
- SQLite「Release 3.39.0」(RIGHT JOIN・FULL JOINに対応したバージョン)
- Microsoft Learn「Joins (SQL Server)」(SQL Serverで使える結合の種類)
練習問題(全5問)
正解:2つ以上の
JOIN
正解:両方の
INNER JOINは、
正解:注文側の
LEFT JOINは、
正解:右側
RIGHT JOINは、
正解:FULL JOINは、
FULL JOINは、
選んでから「採点する」を押すと、解説つきで答え合わせができます。
関連記事
おすすめの本 PR
セキュリティとデータベースは、基本情報技術者試験の対策本でまとめて学べます。

