CROSS JOIN 与 SELF JOIN 是什么
CROSS JOIN 是无条件连接,结果行数等于左右两侧行数的乘积,也就是笛卡尔积;它正确的用法是「有意识地做排列组合」,比如两三个小集合拼枚举,而不是漏写条件的连接。SELF JOIN 是自连接:同一张表起两个别名互相连接,用来比较同表内的不同行,比如层级关系、前后行差值。
基本信息
| 适用版本 | MySQL 5.7 / 8.0 |
|---|---|
| 结果行数 | CROSS JOIN = 左表行数 × 右表行数 |
| 语义等价 | CROSS JOIN 与 FROM a, b 完全相同,只是显式写法更清楚 |
| 自连接要点 | 同一张表必须起两个不同别名 |
| 典型风险 | 误用 CROSS JOIN 产生千万级中间结果 |
典型使用场景
- 生成数字或日期序列:两个小集合 CROSS JOIN 得到枚举值,配合函数拼出日历
- 报表的维度组合:按「渠道 × 品类」补全空格子,保证输出每个组合都有行
- 同表相邻行比较:本行与上一行做差,得出增量或环比
- 层级展开:员工-上级、分类-父分类这类自引用结构逐层查询
- 压力测试造数据:小数据量 CROSS JOIN 快速放大成测试数据集
自连接比较相邻行
自连接比较相邻行
-- 本行与上一行做差,得到每个指标的增量
SELECT a.id, a.value - b.value AS delta
FROM metrics a
JOIN metrics b ON b.id = a.id - 1
WHERE a.id > 1 # 去掉第一条没有前序行的记录
ORDER BY a.id;生成数字序列(小型 CROSS JOIN)
生成数字序列(小型 CROSS JOIN)
-- 10 × 3 = 30 个组合,得到 1 到 30 的序列
SELECT d1.n + d2.n * 10 + 1 AS seq
FROM (SELECT 0 AS n UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) d1
CROSS JOIN (SELECT 0 AS n UNION SELECT 1 UNION SELECT 2) d2
ORDER BY seq;连接类型对照
| 写法 | 结果 | 何时用 |
|---|---|---|
| INNER JOIN ... ON | 只保留匹配行 | 常规关联,最常用 |
| LEFT JOIN ... ON | 保留左表全部行 | 补全缺失维度、找未匹配记录 |
| CROSS JOIN | 左右全组合 | 枚举组合,必须显式且规模可控 |
| FROM a, b | 等同于 CROSS JOIN | 老写法,容易漏条件,建议改显式 |
CROSS JOIN 一旦作用在两张大表上,中间结果会瞬间撑爆临时表与磁盘;线上执行前先用 COUNT(*) 估算两侧行数,或加 LIMIT 试跑,确认计划里没有出现巨量 rows 估算。