跳至正文

Tableau数据混合与SQL NATURAL JOIN

XILEJUN
喜乐君 Tableau Visionary ✦ 5
📊 业务数据分析「专家」· 敏捷 BI 布道师
📚 《数据可视化分析》《业务可视化分析》多本书作者
🎓 中国地质大学(武汉)经管学院 MBA 校外导师
🤝 以 Tableau 会友,致力于构建业务分析通识框架

📚 本文配套课程 · 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 会自动寻找公共列进行匹配。

什么是 SQL NATURAL JOIN

NATURAL JOIN 会在两个表之间,根据名称和数据类型都相同的列来执行连接。它会自动识别这些“公共列”,并在最终的结果集中将这些公共列合并,只保留一个版本,从而使查询结果更简洁,避免了数据冗余。

这种连接的行为模式本质上是一种 INNER JOIN (内连接),只会返回在两个表中公共列的值都能够匹配上的行。

语法:SQL

SELECT *
FROM table1
NATURAL JOIN table2;
概念图展示自然连接(NATURAL JOIN),包含两个表(Table A 和 Table B)与公共列的关系图示。
图片来自 https://www.boardinfinity.com/blog/natural-join-in-dbms-sql/

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

现在,我们在 employeedepartment 表之间执行 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 | 孙七 | 人力资源部 |
示意图展示了 SQL 中 `NATURAL JOIN` 的工作原理,包括两个表之间的公共列和根据这些公共列连接的匹配行。
图片来自 https://www.w3resource.com/mysql/advance-query-in-mysql/mysql-natural-join.php

结果分析

从以上结果可以看出 NATURAL JOIN 的关键特征:

  1. 基数差异处理:尽管 employee 表有 6 行,department 表有 4 行,但最终结果只有 5 行。
  2. 引用完整性特征
    • 员工 ‘周八’ 没有出现在结果中,因为他所属的部门ID 50department 表中不存在。
    • ‘财务部’ 也没有出现在结果中,因为没有任何一名员工被分配到该部门 (ID 40)。
  3. 消除重复列:公共列 $dept\_id$ 在结果中只出现了一次,而不是两次。

这清晰地表明,NATURAL JOIN 只返回那些在两个表中都能找到匹配连接键的记录。


NATURAL JOININNER JOIN 的区别

虽然 NATURAL JOININNER JOIN 都能合并两个表的数据,但它们在用法和行为上有显著区别:

特性NATURAL JOININNER 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

《Tableau数据混合与SQL NATURAL JOIN》有1个想法

  1. Pingback: 临时关系匹配在BI分析中的应用与工具对比

评论已关闭。