📚 本文配套课程 · SQL 系列
🎬 B 站课程:DAX「别裁新解」 — https://www.bilibili.com/cheese/play/ss8780
2025-07-24 参考网络内容,基于 Google Germini Pro2.5 创建
2025/10/07修改,增加混合相关内容的比较——面向国产 BI 设计。
Tableau 混合
Tableau 混合是一个非常重要的功能,它降低了业务用户跨主题分析的难度,又避免了类似于 DAX 的 Related 一样的技术门槛,可以说是 Tableau 成长过程中堪比 关系模型、LOD 一样的核心功能。
从技术上看,混合最终体现为 Join,但它的独特之处在于位置:它在视图聚合之后创建,而非在数据库或数据源层面预先创建。这是混合灵活性的保证。相关内容参见《数据可视化分析(第 2 版):分析原理与 Tableau、SQL 实践》第四章内容。

本文重点,在于介绍 SQL 的“自然连接”,分析师可以把它比作是混合的低阶形式。
NATURAL JOIN (自然连接) 是 SQL 中的一种连接操作,它会基于两个表中所有同名且同数据类型的列来自动合并数据。其核心特点是无需手动指定连接条件,SQL 会自动寻找公共列进行匹配。
- 临时关系匹配在 BI 分析中的作用及工具实现 2025/7
什么是 SQL NATURAL JOIN?
NATURAL JOIN 会在两个表之间,根据名称和数据类型都相同的列来执行连接。它会自动识别这些“公共列”,并在最终的结果集中将这些公共列合并,只保留一个版本,从而使查询结果更简洁,避免了数据冗余。
这种连接的行为模式本质上是一种 INNER JOIN (内连接),只会返回在两个表中公共列的值都能够匹配上的行。
语法:SQL
SELECT *
FROM table1
NATURAL JOIN table2;

NATURAL JOIN 的特点
- 自动匹配列:
NATURAL JOIN会自动寻找两个表中所有名称和类型相同的列作为连接键,无需像INNER JOIN那样使用ON子句手动指定。 - 消除重复列:如果两个表有公共列,
NATUAL JOIN的结果中只会包含该列一次,而不是像其他连接那样可能返回两个同名列。 - 体现引用完整性:它的行为类似于内连接,只有当连接键的值同时存在于两个表中时,相关的数据行才会被返回。这可以用来快速查找那些在两个关联表中都有对应记录的数据。
- 潜在风险 ⚠️:由于连接是自动进行的,如果两个表恰好有多个未预期的同名列(例如
id,name,update_time等),NATURAL JOIN会尝试在所有这些列上进行匹配,这可能导致非预期的结果或返回空集。因此,在生产环境中,显式指定连接条件的INNER JOIN通常是更安全、更清晰的选择。
NATURAL JOIN 实战演练
为了更好地理解,我们通过一个实际案例来演示 NATURAL JOIN 的用法。在这个案例中,我们的两个数据表行数不同,并且存在无法完全对应的数据,以便观察其在引用完整性方面的特征。
第一步: 创建数据表
我们创建两个表:department (部门表) 和 employee (员工表)。
1、部门表 (department)该表包含 4 个部门。
SQLCREATE TABLE department ( dept_id INT PRIMARY KEY, dept_name VARCHAR(50) );
2、员工表 (employee)该表包含 6 名员工。
SQLCREATE TABLE employee
( emp_id INT PRIMARY KEY, emp_name VARCHAR(50), dept_id INT );
第二步: 插入数据
现在,我们向两个表中插入数据。请注意,部门表有4行,员工表有6行。
1、向 department 表插入数据:SQL
INSERT INTO department(dept_id, dept_name) VALUES
(10, '技术部'),
(20, '销售部'),
(30, '人力资源部'),
(40, '财务部'); -- 注意:这个部门将没有员工
2、向 employee 表插入数据:SQL
INSERT INTO employee(emp_id, emp_name, dept_id) VALUES
(101, '张三', 10),
(102, '李四', 10),
(103, '王五', 20),
(104, '赵六', 30),
(105, '孙七', 30),
(106, '周八', 50); -- 注意:这名员工所属的部门ID(50)在部门表中不存在
第三步: 检视数据
执行查询,确认两个表的数据。
SELECT * FROM department;
输出:
| dept_id | dept_name |
| :— | :— |
| 10 | 技术部 |
| 20 | 销售部 |
| 30 | 人力资源部 |
| 40 | 财务部 |
SELECT * FROM employee;
输出:
| emp_id | emp_name | dept_id |
| :— | :— | :— |
| 101 | 张三 | 10 |
| 102 | 李四 | 10 |
| 103 | 王五 | 20 |
| 104 | 赵六 | 30 |
| 105 | 孙七 | 30 |
| 106 | 周八 | 50 |
第四步: 执行 NATURAL JOIN
现在,我们在 employee 和 department 表之间执行 NATURAL JOIN。SQL 会自动发现公共列 $dept\_id$ 并用它来连接。
SQL
SELECT *
FROM employee
NATURAL JOIN department;
输出:
| dept_id | emp_id | emp_name | dept_name |
| 10 | 101 | 张三 | 技术部 |
| 10 | 102 | 李四 | 技术部 |
| 20 | 103 | 王五 | 销售部 |
| 30 | 104 | 赵六 | 人力资源部 |
| 30 | 105 | 孙七 | 人力资源部 |

结果分析
从以上结果可以看出 NATURAL JOIN 的关键特征:
- 基数差异处理:尽管
employee表有 6 行,department表有 4 行,但最终结果只有 5 行。 - 引用完整性特征:
- 员工 ‘周八’ 没有出现在结果中,因为他所属的部门ID
50在department表中不存在。 - ‘财务部’ 也没有出现在结果中,因为没有任何一名员工被分配到该部门 (ID
40)。
- 员工 ‘周八’ 没有出现在结果中,因为他所属的部门ID
- 消除重复列:公共列
$dept\_id$在结果中只出现了一次,而不是两次。
这清晰地表明,NATURAL JOIN 只返回那些在两个表中都能找到匹配连接键的记录。
NATURAL JOIN 与 INNER JOIN 的区别
虽然 NATURAL JOIN 和 INNER JOIN 都能合并两个表的数据,但它们在用法和行为上有显著区别:
| 特性 | NATURAL JOIN | INNER JOIN |
| 连接条件 | 自动基于所有同名同类型列,无需指定。 | 必须手动使用 ON 子句显式指定连接列和条件。 |
| 结果列 | 公共列只出现一次。 | 默认情况下,两个表中的所有列都会出现,包括重复的连接列(需用别名区分)。 |
| 控制力 | 控制力较弱,容易因意外的同名列而出错。 | 控制力强,连接条件清晰明确,是更推荐的做法。 |
使用 INNER JOIN 实现与上面相同的效果,查询语句如下:
SELECT
e.emp_id,
e.emp_name,
d.dept_id,
d.dept_name
FROM
employee AS e
INNER JOIN
department AS d ON e.dept_id = d.dept_id;
可以看到,INNER JOIN 更加冗长,但它的意图也更加清晰和安全。
参考文章:SQL Natural Join
Pingback: 临时关系匹配在BI分析中的应用与工具对比
评论已关闭。