下面以 SQL Server 为例,详细讲解 笛卡尔积(Cartesian Product) 的概念,并提供使用中文字段的示例。
一、什么是笛卡尔积?
在关系型数据库中,笛卡尔积是指两个表在没有指定连接条件(如 ON 或 WHERE)的情况下进行 JOIN 操作时,返回的结果集是第一个表的每一行与第二个表的每一行的所有可能组合。
- 如果表 A 有 m 行,表 B 有 n 行,那么它们的笛卡尔积将包含 m × n 行。
- 在 SQL 中,显式使用
CROSS JOIN会生成笛卡尔积;如果在FROM子句中用逗号连接两个表且未加WHERE条件,也会产生笛卡尔积(这是旧式写法)。
⚠️ 注意:笛卡尔积通常不是我们想要的结果,除非业务场景确实需要所有组合(例如生成所有商品与所有颜色的搭配)。否则应避免,因为它会导致结果集爆炸、性能下降。
二、示例说明(使用中文字段)
假设我们有两个表:
表1:部门表(部门信息)
CREATE TABLE 部门信息 (
部门编号 INT,
部门名称 NVARCHAR(50)
);
INSERT INTO 部门信息 VALUES
(1, N'人力资源部'),
(2, N'技术部');
| 员工编号 | 员工姓名 |
|---|---|
| 101 | 张三 |
| 102 | 李四 |
| 103 | 王五 |
表2:员工表(员工信息)
CREATE TABLE 员工信息 (
员工编号 INT,
员工姓名 NVARCHAR(50)
);
INSERT INTO 员工信息 VALUES
(101, N'张三'),
(102, N'李四'),
(103, N'王五');
| 部门编号 | 部门名称 |
|---|---|
| 1 | 人力资源部 |
| 2 | 技术部 |
三、执行笛卡尔积查询
方法1:使用 CROSS JOIN
SELECT
部门信息.部门名称,
员工信息.员工姓名
FROM
部门信息
CROSS JOIN
员工信息;
方法2:旧式写法(不推荐)
SELECT
部门信息.部门名称,
员工信息.员工姓名
FROM
部门信息, 员工信息;
-- 注意:这里没有 WHERE 条件,所以也是笛卡尔积
四、查询结果
由于 部门信息 有 2 行,员工信息 有 3 行,笛卡尔积结果为 2 × 3 = 6 行:
| 部门名称 | 员工姓名 |
|---|---|
| 人力资源部 | 张三 |
| 人力资源部 | 李四 |
| 人力资源部 | 王五 |
| 技术部 | 张三 |
| 技术部 | 李四 |
| 技术部 | 王五 |
这表示“每个部门与每个员工的所有可能组合”,但现实中一个员工通常只属于一个部门,因此这种结果在大多数业务场景下是错误或无意义的。
五、如何避免意外的笛卡尔积?
- 始终在
JOIN时加上明确的连接条件,例如:
SELECT
d.部门名称,
e.员工姓名
FROM
部门信息 d
INNER JOIN
员工信息 e ON d.部门编号 = e.所属部门编号;
(注意:此例中需在 员工信息 表中增加 所属部门编号 字段才能正确关联)
- 避免在 FROM 中用逗号连接多表而不写 WHERE 条件。
六、总结
- 笛卡尔积 = 所有可能的行组合
- 使用
CROSS JOIN显式生成 - 在无连接条件的多表查询中容易意外产生
- 通常应避免,除非业务明确需要(如生成组合配置、测试数据等)
虽然笛卡尔积(Cartesian Product) 在大多数日常业务查询中是需要避免的“陷阱”,但在某些特定场景下,它其实是有意且高效的工具。以下是几个适合使用笛卡尔积的典型场景
1 2
© 版权声明
THE END















