複数テーブルを 1 つの結果セットにまとめる JOIN の 5 種類を、社員と部署のテーブルで比較します。
結合(JOIN)は、複数のテーブルを関連する列で連結して、1 つの結果テーブルにする SQL の操作です。正規化で分けたテーブルを「使うとき」に元のような表形式に戻すのが主な目的。
例えば社員テーブルと部署テーブルをdept_idで結合すれば、「誰がどの部署にいるか」を 1 つの結果として取得できます。
結合には5 種類があり、「対応する行がないときどう扱うか」で挙動が変わります。上のツールで各種類を切替えて比較できます。
INNER JOIN(内部結合)は、両テーブルの結合条件を満たす行だけを取得します。ベン図でいう「交差部分」に相当。
片方にしかない行(社員側の山田、部署側の人事部)は結果から消えます。「両方に存在するペアだけ」を取り出したいときに使います。
最もよく使われる結合で、単に「JOIN」と書くと多くの DB で INNER JOIN を意味します。
LEFT JOINは左テーブルの全行を残し、右に対応がなければNULL。RIGHT JOINはその逆。
使い分けのコツ:
・LEFT JOIN:「左テーブルは全部欲しい、右側はあれば付ける」
・例:「全社員を表示。所属していれば部署名も表示」 → 山田(部署なし)も結果に含まれる
・RIGHT JOIN:「右テーブルは全部欲しい」
・例:「全部署を表示。社員がいなくても部署は表示」 → 人事部(社員なし)も結果に含まれる
実務では LEFT JOIN の方がよく使われます(テーブルの順序を入れ替えれば LEFT で RIGHT を再現できるため)。
FULL OUTER JOINは両テーブルのすべての行を残します。対応がなければ NULL になる点は LEFT/RIGHT と同じ。
使う場面は限定的:「両方のテーブルにある行も、どちらか片方にしかない行もすべて見たい」というデータ分析や監査用途。MySQL では未サポートのため UNION で代用することもあります。
上のツール「FULL JOIN」シナリオで、山田(左のみ)と人事部(右のみ)が両方とも結果に残っているのを確認できます。
CROSS JOIN(直積)は ON 句なしの結合で、左テーブルの全行と右テーブルの全行のすべての組み合わせを返します。行数は m × n。
4 社員 × 3 部署 = 12 行(上のツールで確認可)。実用ではあまり使いませんが、ON 句を忘れた INNER JOIN はこの CROSS JOIN になってしまい、巨大な結果でサーバーが固まる ── という事故が定期的に起きます。
10000 行 × 10000 行 = 1 億行 という恐ろしい結果になるので、JOIN を書くときは ON 句を絶対に忘れないこと。
結合条件は ON 句で指定します。例:ON 社員.dept_id = 部署.id。
ほぼ全ての結合で「主キーと外部キーの等号」で結合します。これを等結合(equi-join)と呼びます。等号以外(<, >)の条件も書けますが、用途は限定的。
古い書き方として FROM 社員, 部署 WHERE 社員.dept_id = 部署.id もありますが、可読性が悪く、外部結合が書けないため新規コードでは JOIN ... ON 形式を使うのが現代の標準です。