タスクラボ関数リファレンス > SQL JOIN

SQLのJOINの種類と使い分け

対応: 標準SQL(MySQL・PostgreSQL・SQL Server・SQLite ほか)

JOINは2つのテーブルを結合する構文です。種類による違いは「一致しない行を残すかどうか」だけです。同じ2つの表で結果を比べます。

例に使う2つのテーブル

users(会員)
id=1 佐藤/id=2 鈴木/id=3 高橋
orders(注文)
user_id=1 りんご/user_id=1 みかん/user_id=2 ぶどう/user_id=9 メロン

高橋(id=3)は注文なし。user_id=9 の注文は対応する会員なし。この2つの扱いが種類で変わります。

INNER JOIN(両方に存在する行だけ)

SELECT u.name, o.item
FROM users u
INNER JOIN orders o ON u.id = o.user_id;

結果: 佐藤-りんご / 佐藤-みかん / 鈴木-ぶどう
→ 高橋(注文なし)と user_id=9(会員なし)は消える

LEFT JOIN(左の表は全行残す)

SELECT u.name, o.item
FROM users u
LEFT JOIN orders o ON u.id = o.user_id;

結果: 佐藤-りんご / 佐藤-みかん / 鈴木-ぶどう / 高橋-NULL
→ 注文のない高橋も残る(注文列はNULL)。実務で最もよく使う

RIGHT JOIN(右の表は全行残す)

SELECT u.name, o.item
FROM users u
RIGHT JOIN orders o ON u.id = o.user_id;

結果: 佐藤-りんご / 佐藤-みかん / 鈴木-ぶどう / NULL-メロン
→ 会員のいない注文(メロン)も残る。LEFT JOINで表の順番を入れ替えれば同じことができる

FULL OUTER JOIN(両方の全行を残す)

SELECT u.name, o.item
FROM users u
FULL OUTER JOIN orders o ON u.id = o.user_id;

結果: 上の全部 + 高橋-NULL + NULL-メロン
※ MySQLには無い(LEFT JOIN と RIGHT JOIN を UNION して代用)

CROSS JOIN(全組み合わせ)

SELECT u.name, o.item FROM users u CROSS JOIN orders o;

結果: 3人 × 4注文 = 12行。ON句は書かない。組み合わせ表を作るときだけ使う

使い分けの早見表

やりたいこと使うJOIN
注文がある会員だけ集計したいINNER JOIN
注文ゼロの会員も含めて一覧にしたいLEFT JOIN
どちらかにしか無いデータ(不整合)を探したいLEFT JOIN + WHERE 右がNULL(またはFULL OUTER)
マスタ同士の全組み合わせを作りたいCROSS JOIN
LEFT JOINのあとWHERE句で右の列の条件を書くとINNERに化けます。右の列の条件は ON 句に書くか、WHERE (o.x = 1 OR o.x IS NULL) としてください。

関連