Query Go
全組み合わせを作る - CROSS JOIN の使い方・オプション・サンプル

全組み合わせを作る - CROSS JOIN

結合条件を持たず、左右すべての行の組み合わせ(デカルト積)を返す結合

概念図

CROSS JOIN diagram

構文

sql
SELECTFROM A CROSS JOIN B

サンプル

サイズ一覧と色一覧の全組み合わせを生成(バリエーション生成)

sql
SELECT s.size, c.color
FROM sizes s
CROSS JOIN colors c;

CROSS JOIN とは

CROSS JOIN は 結合条件を持たず、左右すべての行の組み合わせ(デカルト積 / Cartesian product)を返します。左が m 行、右が n 行なら結果は m × n 行になります。

商品のサイズ × カラーのような全組み合わせ生成や、日付シーケンス × ユーザーのような疎なデータ埋めに使われます。

暗黙のカンマ結合

FROM 句にカンマでテーブルを並べる古い書き方も実質的に CROSS JOIN と同じです。FROM a, b WHERE a.id = b.idFROM a CROSS JOIN b WHERE a.id = b.id と等価ですが、ON で書く明示結合が推奨されます。

sql
-- 推奨されない古い書き方
SELECT * FROM users u, orders o WHERE o.user_id = u.id;

-- 推奨される明示結合
SELECT * FROM users u INNER JOIN orders o ON o.user_id = u.id;

LATERAL / CROSS APPLY への軽い言及

各行ごとに相関サブクエリの結果と結合したい場合は、CROSS JOIN ではなく CROSS JOIN LATERAL(PostgreSQL)や CROSS APPLY(SQL Server)を使います。たとえば「各ユーザーの最新3件の注文」のような処理に向きます。MySQL は 8.0.14+ で LATERAL サポート、SQLite は未サポート。

事故に注意

  • 結合条件の付け忘れで意図せずデカルト積になると、100万行 × 100万行 = 1兆行のような爆発が起きる
  • 実行計画に CROSS JOINNested Loop (no join condition) が出たら要確認
  • 意図して使う場合は必ず CROSS JOIN と明示し、コメントで意図を残す

関連トピック