MySQL内、外连接知识点汇总

以下是 SQL 外连接的完整讲解,包含INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL JOIN 以及内、外连接的核心概念,全部用表格举例说明。


一、内连接 vs 外连接核心区别

表格

复制

对比项 内连接 (INNER JOIN) 外连接 (LEFT/RIGHT/FULL JOIN)
匹配规则 只返回两表匹配的行 返回匹配行 + 未匹配行(补 NULL)
结果集大小 ≤ 两表匹配行数 ≥ 内连接结果(可能更大)
未匹配数据处理 丢弃 保留,缺失侧补 NULL
使用场景 只关心两表都有的数据 需要保留某表全部数据
图示 两圆交集 左圆 / 右圆 / 两圆全部

二、示例数据表

employees 员工表(左表)

表格

emp_id emp_name dept_id
1 张三 10
2 李四 20
3 王五 10
4 赵六 NULL
5 孙七 50

departments 部门表(右表)

表格

dept_id dept_name
10 技术部
20 销售部
30 财务部

三、INNER JOIN(内连接)回顾

sql

复制代码
SELECT e.emp_name, d.dept_name
FROM employees e
INNER JOIN departments d ON e.dept_id = d.dept_id;

结果:

表格

emp_name dept_name 说明
张三 技术部 匹配
王五 技术部 匹配
李四 销售部 匹配

未匹配的行被丢弃:赵六(dept_id=NULL)、孙七(dept_id=50 无对应部门)、财务部(无员工)


四、LEFT JOIN(左外连接)

语法

sql

复制代码
SELECT e.emp_name, d.dept_name
FROM employees e
LEFT JOIN departments d ON e.dept_id = d.dept_id;

规则

表格

规则 说明
保留左表全部行 employees 表所有 5 条记录都出现
右表匹配不上 补 NULL
右表有多条匹配 左表行重复显示

结果

表格

emp_name dept_name 来源分析
张三 技术部 左表 + 右表匹配
王五 技术部 左表 + 右表匹配
李四 销售部 左表 + 右表匹配
赵六 NULL 左表有,右表无匹配(dept_id=NULL)
孙七 NULL 左表有,右表无匹配(dept_id=50 不存在)

使用场景

表格

场景 示例
查询所有员工,不管有没有部门 SELECT * FROM employees LEFT JOIN departments
查询未分配部门的员工 WHERE d.dept_id IS NULL
查询所有订单及客户信息(含未下单客户) 客户表 LEFT JOIN 订单表

五、RIGHT JOIN(右外连接)

语法

sql

复制代码
SELECT e.emp_name, d.dept_name
FROM employees e
RIGHT JOIN departments d ON e.dept_id = d.dept_id;

规则

表格

规则 说明
保留右表全部行 departments 表所有 3 条记录都出现
左表匹配不上 补 NULL

结果

表格

emp_name dept_name 来源分析
张三 技术部 右表 + 左表匹配
王五 技术部 右表 + 左表匹配
李四 销售部 右表 + 左表匹配
NULL 财务部 右表有,左表无匹配(无员工)

使用场景

表格

场景 示例
查询所有部门,不管有没有员工 RIGHT JOINLEFT JOIN 换表顺序
查询没有员工的部门 WHERE e.emp_id IS NULL

注意:RIGHT JOIN 实际开发中较少使用,通常用 LEFT JOIN + 换表顺序替代,更易读。


六、FULL JOIN(全外连接)

语法

sql

复制代码
SELECT e.emp_name, d.dept_name
FROM employees e
FULL JOIN departments d ON e.dept_id = d.dept_id;

规则

表格

规则 说明
保留两表全部行 左表 + 右表所有记录都出现
匹配不上的 各自补 NULL
结果集 LEFT JOIN 结果 ∪ RIGHT JOIN 结果

结果

表格

emp_name dept_name 来源分析
张三 技术部 两表匹配
王五 技术部 两表匹配
李四 销售部 两表匹配
赵六 NULL 仅左表有
孙七 NULL 仅左表有
NULL 财务部 仅右表有

MySQL 特殊说明

表格

数据库 FULL JOIN 支持
PostgreSQL ✅ 原生支持
SQL Server ✅ 原生支持
Oracle ✅ 原生支持
MySQL 不支持

MySQL 实现 FULL JOIN 的替代方案:

sql

复制代码
-- UNION 合并 LEFT + RIGHT
SELECT e.emp_name, d.dept_name
FROM employees e
LEFT JOIN departments d ON e.dept_id = d.dept_id

UNION

SELECT e.emp_name, d.dept_name
FROM employees e
RIGHT JOIN departments d ON e.dept_id = d.dept_id;

七、四种连接对比总表

表格

连接类型 保留左表全部 保留右表全部 结果行数 图示
INNER JOIN 3行(仅匹配) 两圆交集
LEFT JOIN 5行(左表全部) 左圆全部
RIGHT JOIN 4行(右表全部) 右圆全部
FULL JOIN 6行(两表全部) 两圆全部

八、未匹配数据筛选(经典场景)

场景1:查询没有部门的员工

sql

复制代码
SELECT e.emp_name
FROM employees e
LEFT JOIN departments d ON e.dept_id = d.dept_id
WHERE d.dept_id IS NULL;

结果:

表格

emp_name
赵六
孙七

场景2:查询没有员工的部门

sql

复制代码
SELECT d.dept_name
FROM employees e
RIGHT JOIN departments d ON e.dept_id = d.dept_id
WHERE e.emp_id IS NULL;

-- 或更常见的写法(LEFT JOIN 换顺序)
SELECT d.dept_name
FROM departments d
LEFT JOIN employees e ON d.dept_id = e.dept_id
WHERE e.emp_id IS NULL;

结果:

表格

dept_name
财务部

场景3:查询两表完全无关联的数据(MySQL 模拟 FULL JOIN 取差集)

sql

复制代码
-- 没有部门的员工 + 没有员工的部门
SELECT e.emp_name, d.dept_name
FROM employees e
LEFT JOIN departments d ON e.dept_id = d.dept_id
WHERE d.dept_id IS NULL

UNION

SELECT e.emp_name, d.dept_name
FROM departments d
LEFT JOIN employees e ON d.dept_id = e.dept_id
WHERE e.emp_id IS NULL;

结果:

表格

emp_name dept_name
赵六 NULL
孙七 NULL
NULL 财务部

九、实际开发选择指南

表格

需求 应使用的连接
只查两表都有的数据 INNER JOIN
查 A 表全部 + B 表匹配数据 A LEFT JOIN B
查 B 表全部 + A 表匹配数据 B LEFT JOIN A(推荐)或 A RIGHT JOIN B
查 A 表独有的数据 A LEFT JOIN B WHERE B.key IS NULL
查 B 表独有的数据 B LEFT JOIN A WHERE A.key IS NULL
查两表全部(含未匹配) FULL JOIN(MySQL 用 UNION 模拟)
查两表各自独有的数据 (A LEFT JOIN B WHERE B IS NULL) UNION (B LEFT JOIN A WHERE A IS NULL)

十、一句话总结

表格

连接 口诀
INNER JOIN 两表都有才保留
LEFT JOIN 左表全留,右表没有补 NULL
RIGHT JOIN 右表全留,左表没有补 NULL
FULL JOIN 两表全留,各自没有补 NULL
相关推荐
登登登__8 分钟前
春秋招笔试题总结
java·开发语言
大家的林语冰11 分钟前
👍 超越 ESLint,Oxc 优先采用 TypeScript 7,Rust 和 Go 梦幻联动!
前端·javascript·typescript
上海云盾商务经理杨杨12 分钟前
SQL 盲注入渗透实战!无报错页面也能成功注入
数据库·sql
rannn_11115 分钟前
【力扣hot100】链表专题|21、2、19、24、92、25
java·数据结构·算法·leetcode·链表·开发
秋田君43 分钟前
QT_绘图原理双缓冲机制
服务器·数据库·qt
Rabitebla1 小时前
C++11 新特性详解(一):列表初始化、initializer_list 与右值引用
java·开发语言·数据结构·c++·算法·leetcode·list
洋不写bug1 小时前
JavaComparable、Comparator、Cloneable接口解析,深拷贝浅拷贝详细解析
android·java·开发语言
坐吃山猪1 小时前
WebFlux_学习Subscriber总结
java·开发语言·学习·webflux
一条闲鱼_mytube1 小时前
深入理解 Pinecone 向量数据库:从云服务到索引原理,一篇讲透
数据库
白露与泡影1 小时前
Java面试题及答案整理(2026年金九银十最新版,持续更新)
java·开发语言