首页/数据/SQL 速查/CROSS JOIN 笛卡尔积

CROSS JOIN 笛卡尔积

两表无条件配对得到所有组合:常用于生成“尺码 × 颜色”这类组合集,误用时行数按乘积增长。

SQL 速查数据更新于 2026-10-13

CROSS JOIN 是什么

CROSS JOIN 把两张表无条件配对,结果行数是两边行数的乘积。它有两种完全不同的用途:主动生成组合集(尺码 × 颜色、日期 × 门店),用来补全报表里应当为 0 的行;以及被误用——多表查询漏写连接条件,结果集瞬间膨胀。MySQL 里 CROSS JOIN 带 ON 会被当作内连接处理,PostgreSQL 保持严格的笛卡尔积语义,写 INNER JOIN … ON 更不容易产生歧义。

基本信息

结果行数左表行数 × 右表行数
等价写法FROM a, b(不带连接条件时的隐式交叉连接)
MySQL 细节CROSS JOIN 带 ON 条件时按内连接处理
PostgreSQL严格保持笛卡尔积语义,需要条件时改写为 INNER JOIN … ON
规模风险两张大表交叉会产生海量行,聚合指标随之失真

典型使用场景

  • 生成维度组合骨架:尺码 × 颜色、日期 × 门店
  • 补全报表零值行:骨架与事实表 LEFT JOIN 后用 COALESCE 补 0
  • 构造测试数据:把两个小维度交叉得到用例组合
  • 交叉分析:小维度之间的两两比对
  • 排查多表查询漏写连接条件导致的行数膨胀

主动使用:组合骨架

主动使用:组合骨架
-- 生成 尺码 × 颜色 的组合集
SELECT s.size, c.color
FROM sizes s
CROSS JOIN colors c
ORDER BY s.size, c.color;

-- 日期 × 门店 骨架,再左连接真实销量,补出零值行
SELECT d.d, sh.id AS shop_id, COALESCE(t.amount, 0) AS amount
FROM (SELECT DISTINCT stat_date AS d FROM daily_stats) d
CROSS JOIN shops sh
LEFT JOIN daily_stats t
       ON t.stat_date = d.d AND t.shop_id = sh.id
ORDER BY d.d, sh.id;

使用要点与风险

要点说明风险
行数等于两边行数的乘积大表之间交叉会瞬间产生海量行
组合骨架适合几十到几百行的小维度表明细表参与时必须先去重
补零值配合 LEFT JOIN 与 COALESCE 使用要确认业务上确实存在「应为 0」的行
误用多表查询漏写连接条件结果膨胀且往往不报错,很难察觉
生成组合骨架时两边都应是去重后的小维度集合;如果其中一边是明细表,先按维度去重再交叉,否则骨架本身已经膨胀,后续连接与聚合都会变慢。
两表都忘写连接条件时结果按乘积增长(1000 × 1000 即百万行),生产查询上线前务必核对实际返回行数与 EXPLAIN 估算行数是否匹配。

易错点

  • 多表查询漏写连接条件,行数按乘积膨胀,聚合指标全部失真
  • 拿两个明细表做 CROSS JOIN 生成骨架,骨架本身就过大
  • 在 PostgreSQL 里给 CROSS JOIN 加 ON 条件,语法报错,应改写成 INNER JOIN … ON
  • 依赖笛卡尔积的输出顺序(以为会按第一张表顺序返回),实际顺序不保证

数据来源与参考

  • MySQL 8.0 Reference Manual · JOIN · CROSS JOIN
  • PostgreSQL Documentation · CROSS JOIN
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌