INNER JOINは結合条件を満たす行の組を返し、OUTER JOINは指定した側の一致しない行も残します。結合は行同士の組合せであり、単に2つの集合の共通部分を取り出す操作とは異なります。
同じ元データで結果を比較
社員は「1:青木、2:井上、3:上田」、注文は「101:社員1、102:社員1、103:社員2」とします。社員IDで結合すると、社員1には注文が2件対応します。
| 結合後の社員ID | 氏名 | 注文ID |
|---|---|---|
| 1 | 青木 | 101 |
| 1 | 青木 | 102 |
| 2 | 井上 | 103 |
上の表がINNER JOINの結果です。社員1は2行になります。LEFT JOINなら、さらに[3, 上田, NULL]が加わります。社員を全部残す場合でも、結果が社員数と同じ行数になるとは限りません。
INNER・LEFT・RIGHT・FULL
| 種類 | 残す行 |
|---|---|
| INNER JOIN | ON条件が真になる行の組 |
| LEFT OUTER JOIN | 一致する組に加え、左側の一致しない行 |
| RIGHT OUTER JOIN | 一致する組に加え、右側の一致しない行 |
| FULL OUTER JOIN | 一致する組に加え、両側の一致しない行 |
外部結合で対応がない側の列はNULLで補われます。元の表にNULLがあれば内部結合の結果にもNULLが出ることがあり、NULLの多さだけでは結合方法を判別できません。
SELECT e.employee_id, e.name, o.order_id
FROM employees AS e
LEFT JOIN orders AS o
ON e.employee_id = o.employee_id;
このSQLは社員を左側に置いて残す例です。表・列名は説明用です。LEFT JOINはLEFT OUTER JOINと同じ意味で、OUTERを省略できます。
ONとWHEREで結果が変わる
LEFT JOINの後にWHERE o.status = ‘paid’と書くと、注文のない社員のstatusはNULLなので条件が真にならず、その社員は除かれます。社員を残しながら支払済み注文だけ結合したいなら、その条件をONへ入れるなど、どの段階で絞るかを考えます。
NULLと行数の注意点
通常の等価条件ではNULL同士を「=」で比較しても真になりません。また、対応する行が複数ならその分結果が増えます。同じ条件・射影でWHEREなどを加える前なら外部結合は内部結合の行を含みますが、行数が必ず多くなるわけではありません。
行・列・結合の区別は、関係演算の記事で整理できます。
確認問題
社員1に注文が2件、社員2には注文がありません。社員を左にしてLEFT JOINした結果は、社員IDごとに何行でしょうか?
解答・解説を見る
社員1は注文ごとに2行、社員2は注文側をNULLで補った1行です。LEFT JOINは左の行を残しますが、左表と同じ行数になるとは限りません。
SQLの取り出し方をnoteで復習
無料noteにはJOIN・内部結合・外部結合・NULLの説明があります。結合の結果を理解した後は、WHEREや集計と合わせたSQLの読み方を復習できます。
無料note:SELECT・JOINとSQL頻出ポイントを学ぶ
ほかの教材は資格・目的別のnote教材ナビから選べます。

コメント