虽然笛卡尔积(Cartesian Product) 在大多数日常业务查询中是需要避免的“陷阱”,但在某些特定场景下,它其实是有意且高效的工具。以下是几个适合使用笛卡尔积的典型场景.
应用场景
✅ 场景 1:生成所有可能的组合(组合爆炸)
适用情况:需要枚举两个或多个维度的所有组合。
示例:生成所有“产品 × 颜色”组合用于商品上架
-- 产品表
CREATE TABLE 产品 (
产品ID INT,
产品名称 NVARCHAR(50)
);
INSERT INTO 产品 VALUES (1, N'T恤'), (2, N'帽子');
-- 颜色表
CREATE TABLE 颜色 (
颜色ID INT,
颜色名称 NVARCHAR(20)
);
INSERT INTO 颜色 VALUES (1, N'红色'), (2, N'蓝色'), (3, N'黑色');
需求:为每种产品生成所有可用颜色的 SKU 草稿。
SELECT
p.产品名称,
c.颜色名称,
CONCAT(p.产品名称, '-', c.颜色名称) AS SKU名称
FROM
产品 p
CROSS JOIN
颜色 c;
结果(2 × 3 = 6 行):
| 产品名称 | 颜色名称 | SKU名称 |
|---|---|---|
| T恤 | 红色 | T恤-红色 |
| T恤 | 蓝色 | T恤-蓝色 |
| T恤 | 黑色 | T恤-黑色 |
| 帽子 | 红色 | 帽子-红色 |
| 帽子 | 蓝色 | 帽子-蓝色 |
| 帽子 | 黑色 | 帽子-黑色 |
✅ 这正是业务需要的“全组合”。
✅ 场景 2:生成日期维度与分类维度的完整报表骨架
适用情况:制作报表时,即使某天某个分类没有数据,也要显示为 0(避免图表断点)。
示例:生成“2025年1月每天 × 所有销售区域”的空骨架
-- 销售区域
CREATE TABLE 区域 (
区域名称 NVARCHAR(20)
);
INSERT INTO 区域 VALUES (N'华北'), (N'华东'), (N'华南');
-- 生成2025年1月所有日期(SQL Server 用递归CTE)
WITH 日期序列 AS (
SELECT CAST('2025-01-01' AS DATE) AS 日期
UNION ALL
SELECT DATEADD(DAY, 1, 日期)
FROM 日期序列
WHERE 日期 < '2025-01-31'
)
SELECT
d.日期,
r.区域名称,
0 AS 销售额 -- 后续可 LEFT JOIN 实际销售数据填充
FROM
日期序列 d
CROSS JOIN
区域 r
OPTION (MAXRECURSION 31);
✅ 这样就能确保报表中每一天、每个区域都有记录,即使当天无销售。
✅ 场景 3:测试数据生成
适用情况:开发或测试阶段需要大量模拟数据。
-- 模拟100个用户 × 50个商品 的浏览记录(用于压力测试)
WITH 用户编号 AS (
SELECT TOP 100 ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS 用户ID
FROM sys.objects a, sys.objects b
),
商品编号 AS (
SELECT TOP 50 ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS 商品ID
FROM sys.objects
)
SELECT
u.用户ID,
p.商品ID,
GETDATE() AS 浏览时间
INTO 测试_用户浏览记录
FROM
用户编号 u
CROSS JOIN
商品编号 p;
✅ 快速生成 100 × 50 = 5000 条测试数据。
✅ 场景 4:配置规则矩阵(如权限、定价策略)
适用情况:为“角色 × 功能”或“客户等级 × 服务类型”预设默认规则。
SELECT
角色.角色名称,
功能.功能名称,
0 AS 是否允许 -- 默认禁止,后续可 UPDATE 特定组合
FROM
(VALUES (N'管理员'), (N'普通用户'), (N'访客')) AS 角色(角色名称)
CROSS JOIN
(VALUES (N'删除数据'), (N'导出报表'), (N'修改配置')) AS 功能(功能名称);
✅ 一次性初始化完整的权限矩阵。
⚠️ 使用建议
| 建议 | 说明 |
|---|---|
显式使用 CROSS JOIN | 不要用逗号连接表,避免误操作 |
| 控制数据量 | 确保参与笛卡尔积的表行数不会导致结果爆炸(如 1万 × 1万 = 1亿行) |
| 配合后续过滤或聚合 | 通常笛卡尔积只是中间步骤,后续会结合 WHERE、LEFT JOIN 或 GROUP BY 使用 |
❌ 不适合的场景(常见误区)
- 查询员工及其所属部门(应使用
INNER JOIN ON 部门ID) - 统计订单和客户信息(需关联主外键)
- 任何有明确业务关联关系的表之间
总结
| 适合使用笛卡尔积的场景 | 关键特征 |
|---|---|
| 生成全组合(产品×颜色、课程×时间段) | 需要“所有可能搭配” |
| 构建报表骨架(日期×分类) | 保证完整性,防止缺失 |
| 生成测试数据 | 快速构造多维模拟数据 |
| 初始化配置矩阵(角色×权限) | 预设默认规则 |
只要目的明确、数据规模可控,笛卡尔积就是一个强大而合法的 SQL 工具!
1 2
© 版权声明
THE END















