当前位置: 首页 > news >正文

SQL:JOIN 进阶

目录

JOIN 是什么?

 🔹OUTER JOIN(外连接)

外连接的分类

外连接与内连接的区别

🔹USING 子句 

语法结构

 和 ON 的对比

📘USING 的内部逻辑 

🧩 多个字段的 USING

USING 的 SELECT 特性(字段可见性)

配合 JOIN 类型的效果

🔹NATURAL JOIN(自然连接)

基本语法:

🔄 执行机制

🔍 对比示例

隐藏风险 ⚠️ 

字段选择行为(结果特征)

自然连接的变体语法(扩展)

NATURAL JOIN vs USING vs ON

🧩 JOIN 的本质回顾:有条件的笛卡尔积


JOIN 是什么?

JOIN 本质上是“笛卡尔积 + 条件筛选”。

在关系数据库中,两个表的连接最原始的操作就是笛卡尔积,即将表 A 和表 B 的所有行做组合,然后通过连接条件筛选我们真正需要的数据。

本篇文章将从以下几个方面,带你走进 JOIN 的进阶世界:

  • 外连接的完整逻辑

  • 更优雅的连接方式:USING 子句

  • 自动化但需谨慎使用的 NATURAL JOIN


 🔹OUTER JOIN(外连接)

在实际开发中,我们常常使用 INNER JOIN 来筛选匹配成功的数据行。然而,这种连接方式默认忽

略未匹配的记录,在某些业务场景(如数据缺失分析、审计对比、错误检测)中反而是不利的。 

外连接是一种可以保留未匹配记录的连接方式,它不仅保留匹配成功的行,还会保留某一方或双方

表中未能匹配的行,并对缺失部分用 NULL 补全。 

外连接的分类

类型含义说明
LEFT OUTER JOIN保留左表所有记录,右表无法匹配的补 NULL
RIGHT OUTER JOIN保留右表所有记录,左表无法匹配的补 NULL
FULL OUTER JOIN保留左右两表所有记录,无法匹配部分用 NULL 补全

📌 注意:通常 SQL 中 OUTER 关键字可以省略。

外连接与内连接的区别

比较维度INNER JOINOUTER JOIN(LEFT/RIGHT/FULL)
匹配条件只保留匹配成功的行匹配成功 + 不匹配的行(补 NULL)
连接结果小于等于原始行数大于等于参与表的行数
典型使用场景严格一一匹配需求需要查看未关联数据

⚠️ MySQL 不直接支持 FULL OUTER JOIN 


 

🔹USING 子句 

我们在之前的 JOIN 中,经常会写出类似 ON a.id = b.id 的重复性语句。USING 是一种语法糖,

当连接字段在两个表中字段名完全一致时,它可以大幅度简化写法。

USING 子句是 JOIN 中的语法简写,用于当连接字段在两个表中字段名相同时,代替 ON a.col = b.col 的写法。

语法结构

SELECT column_list
FROM table1
JOIN table2
USING (column_name);

多个字段:

SELECT column_list
FROM table1
JOIN table2
USING (column1, column2);

🔸 支持:INNER JOINLEFT JOINRIGHT JOINFULL OUTER JOIN
🔸 不支持:CROSS JOIN(因为它没有连接条件)

⚠️ 注意事项

  1. USING 中指定的字段必须在两个表中都存在且字段名一致

  2. 仅支持等值连接(=

  3. SELECT 出来的结果中,这些字段只会显示一次(不是 table1.col 和 table2.col,而是一个简化字段)

 和 ON 的对比

使用 ON 的写法:

SELECT *
FROM employees e
JOIN departments d
ON e.dept_id = d.dept_id;

等价的 USING 写法:

SELECT *
FROM employees
JOIN departments
USING (dept_id);

💡 两者效果一致,差异是:

  • ON 写法结果中会保留 e.dept_idd.dept_id 两列;

  • USING 写法只保留一列 dept_id,更整洁。

📘USING 的内部逻辑 

在执行阶段,SQL 引擎会将:

JOIN USING (col)

转换为:

JOIN ON table1.col = table2.col

然后只保留一个 col 字段,不显示来源表名。

🧩 多个字段的 USING

你可以使用多个字段作为连接条件(必须字段名都一样):

SELECT *
FROM orders o
JOIN deliveries d
USING (order_id, delivery_date);

 这相当于:

ON o.order_id = d.order_id AND o.delivery_date = d.delivery_date

USING 的 SELECT 特性(字段可见性)

考虑如下例子:

SELECT *
FROM employees
JOIN departments
USING (dept_id);

结果中:

  • dept_id 只出现一次

  • 你不能在 SELECT 中写 employees.dept_iddepartments.dept_id,会报错

💡 所以在使用 USING 时,如果你需要区分字段来源,就不要用 USING,用 ON 更灵活

配合 JOIN 类型的效果

JOIN 类型是否支持 USING非匹配字段是否保留输出字段
INNER JOIN公共字段只显示一次
LEFT JOIN左表全部保留同上
RIGHT JOIN右表全部保留同上
FULL OUTER JOIN✅(部分数据库)两表全部保留同上

🔹NATURAL JOIN(自然连接)

NATURAL JOIN 是一种自动基于两个表中相同列名进行连接的语法,无需显式指定连接条件。 

基本语法:

SELECT column_list
FROM table1
NATURAL JOIN table2;

支持的连接类型有:

  • NATURAL JOIN(即自然内连接)

  • NATURAL LEFT JOIN

  • NATURAL RIGHT JOIN

  • NATURAL FULL OUTER JOIN(部分数据库支持)

🔄 执行机制

自然连接的执行过程分为三步:

  1. 自动识别两个表中字段名相同的列

  2. 对这些列执行等值连接(相当于 ON a.col = b.col)

  3. 结果中只保留一份这些列,不重复显示

 注意:这是隐式行为,你无法控制哪些字段被用于连接,只要名字一样,它就会加入连接条件中。

🔍 对比示例

我们以两个表为例:

表A:students

id

name

class_id

1

Alice

101

2

Bob

102

表B:classes

class_idteacher
101Zhang
102Wang

 使用 NATURAL JOIN:

SELECT *
FROM students
NATURAL JOIN classes;

 相当于:

SELECT students.id, students.name, students.class_id, classes.teacher
FROM students
JOIN classes
ON students.class_id = classes.class_id;

但注意:

  • class_id 只显示一列,不是 students.class_idclasses.class_id 两列。

隐藏风险 ⚠️ 

虽然语法简洁,但 NATURAL JOIN 有两个致命隐患:

1️⃣ 字段名意外冲突

如果两个表中存在同名但不相关的列,它们也会被自动用于连接,可能导致:

  • 错误连接逻辑

  • 无结果

  • 数据误导

示例:

-- students 和 exams 表都有 name 字段,但不是用于连接的
SELECT *
FROM students
NATURAL JOIN exams;

这里 name 字段会被用于连接,结果可能完全不符合预期。

2️⃣ 表结构变动敏感

只要某个字段名在两个表中变得相同(或不同),NATURAL JOIN 的行为会自动改变,增加 SQL 的不可预测性与维护难度。

字段选择行为(结果特征)

  • 所有同名字段:只显示一列(不带表前缀)

  • 非同名字段:分别显示原始表字段

自然连接的变体语法(扩展)

类型说明
NATURAL JOIN自然内连接(只返回匹配行)
NATURAL LEFT JOIN左自然外连接(左表全部保留)
NATURAL RIGHT JOIN右自然外连接(右表全部保留)
NATURAL FULL OUTER JOIN全自然外连接(两个表全部保留)

⚠️ FULL OUTER 在 MySQL 中不支持。

NATURAL JOIN vs USING vs ON

特性NATURAL JOINUSING 子句ON 子句
连接字段是否自动识别✅(自动找同名字段)❌(手动指定)❌(完全手动)
是否必须字段名一致✅ 必须一致✅ 仅 USING 中字段需一致❌ 不要求一致
连接条件是否灵活❌ 只能等值❌ 只能等值✅ 任意逻辑、范围比较等
SELECT 中字段出现情况同名字段只出现一次USING 字段只出现一次字段全部保留
可控性❌ 极低✅ 中等✅✅ 极高
推荐使用❌ 不推荐✅ 推荐✅✅ 强烈推荐

🧩 JOIN 的本质回顾:有条件的笛卡尔积

JOIN 的底层其实是生成两个表的笛卡尔积,再通过连接条件进行筛选,不同 JOIN 类型只是在“保留未匹配数据”的策略上不同。

 

相关文章:

  • Tenacity 高级使用指南:Python 重试机制的终极解决方案
  • 学习日志04 java
  • MYSQL之表的约束
  • Redis 中常见的数据类型有哪些?
  • 深度强化学习有什么学习建议吗?
  • telnetlib源码深入解析
  • FanControl(电脑风扇转速控制软件) v224 中文版
  • python学习打卡day23
  • DHCP自动分配IP
  • 仪器设备行业实验室管理现状 质检LIMS系统在仪器设备行业的应用
  • 十二、操作符重载
  • 项目售后服务承诺书,软件售后服务方案,软件安装文档,操作文档,维护文档(Word原件)
  • 在CentOS 7上仅安装部署MySQL 8.0客户端
  • 在Text-to-SQL任务中应用过程奖励模型
  • AI中的MCP是什么?MCP的作用及未来方向预测 (使用go-zero 快速搭建MCP服务器)
  • 如何使用主机名在 CMD 中查找 IP 地址?
  • M0基础篇之DAC
  • 华为行业认证是什么?如何考取华为行业认证?
  • BUUCTF 大流量分析(三) 1
  • HAProxy + Keepalived + Nginx 高可用负载均衡系统
  • 高波︱忆陈昊:在中年之前离去
  • 2025上海科技节本周六启幕,机器人和科学家同走AI科学红毯
  • 比特币挖矿公司GRYP股价涨超171%:将与特朗普儿子创设的公司合并
  • 寒武纪陈天石:公司的产品力获得了行业客户广泛认可,芯片市场有望迎来新增量需求
  • 国家统计局今年将在全国开展两次人口固定样本跟访调查
  • 中国工程院院士、国医大师石学敏逝世