在 MySQL 多表查询中,表连接 是最核心、最常用的知识点,不管是业务开发还是面试,都是高频考点。这篇博客我用最通俗的语言,带你彻底搞懂内连接、左外连接、右外连接,看完直接上手写 SQL。
一、先搞懂:为什么需要表连接?
实际业务里,数据不会只存在一张表中。比如:
- 员工信息存在
emp表 - 部门信息存在
dept表 - 学生信息存在
stu表,成绩存在exam表
想同时查员工 + 部门、学生 + 成绩 ,就必须用表连接,把多张表按关联字段拼起来查询。
表连接本质:把多张表按关联条件组合,返回符合要求的结果集。
二、内连接(INNER JOIN):只保留匹配的数据
1. 核心概念
内连接 = 取两张表的交集 只返回两张表能匹配上 的数据,匹配不上的直接丢弃。
我们平时写的 from 表1,表2 where 条件,本质就是内连接。
2. 标准语法
sql
SELECT 字段名
FROM 表1
INNER JOIN 表2
ON 连接条件
AND 其他筛选条件;
INNER JOIN:内连接关键字ON:写表与表之间的关联条件(必须有)AND:额外的筛选条件
3. 实战案例
需求:查询员工 SMITH 的名字和所属部门名称。
sql
-- 老式写法(等价内连接)
SELECT ename, dname
FROM emp, dept
WHERE emp.deptno = dept.deptno
AND ename = 'SMITH';
-- 标准内连接写法(推荐)
SELECT ename, dname
FROM emp
INNER JOIN dept
ON emp.deptno = dept.deptno
AND ename = 'SMITH';
✅ 结果:只返回 SMITH 及其对应部门,无匹配的数据不会出现。
三、外连接:保留 "不匹配" 的数据
外连接和内连接最大区别:会保留某张表的全部数据,即使另一张表没有匹配项,也会显示,补 NULL。
外连接分两种:左外连接(LEFT JOIN)、右外连接(RIGHT JOIN)。
1. 左外连接(LEFT JOIN):左边表全显示
核心概念
- 左表完全显示
- 右表只显示匹配上的数据
- 匹配不上 → 右表字段补
NULL
标准语法
sql
SELECT 字段名
FROM 表1(左表)
LEFT JOIN 表2(右表)
ON 连接条件;
实战案例
先建测试表:
sql
-- 学生表
CREATE TABLE stu (id INT, name VARCHAR(30));
INSERT INTO stu VALUES(1,'jack'),(2,'tom'),(3,'kity'),(4,'nono');
-- 成绩表
CREATE TABLE exam (id INT, grade INT);
INSERT INTO exam VALUES(1, 56),(2,76),(11, 8);
需求:查询所有学生的成绩,没成绩的学生也要显示。
sql
SELECT *
FROM stu
LEFT JOIN exam
ON stu.id = exam.id;
✅ 结果:
- jack、tom:有成绩,正常显示
- kity、nono:无成绩,成绩字段显示 NULL
- 成绩表 11 号:不匹配学生,不显示
2. 右外连接(RIGHT JOIN):右边表全显示
核心概念
- 右表完全显示
- 左表只显示匹配上的数据
- 匹配不上 → 左表字段补
NULL
标准语法
sql
SELECT 字段名
FROM 表1
RIGHT JOIN 表2(右表)
ON 连接条件;
实战案例
需求:显示所有成绩,哪怕没有学生对应也要显示。
sql
SELECT *
FROM stu
RIGHT JOIN exam
ON stu.id = exam.id;
✅ 结果:
- 成绩 1、2、11 全部显示
- 11 号成绩无匹配学生,学生字段补 NULL
四、高频练习:部门 + 员工(经典面试题)
需求:列出所有部门名称 + 员工信息,包括没有员工的部门。
两种等价写法:
sql
-- 方法1:部门左连接员工(推荐)
SELECT d.dname, e.*
FROM dept d
LEFT JOIN emp e
ON d.deptno = e.deptno;
-- 方法2:员工右连接部门
SELECT d.dname, e.*
FROM emp e
RIGHT JOIN dept d
ON d.deptno = e.deptno;
✅ 效果:所有部门都显示,没员工的部门,员工字段为 NULL。
五、一张图总结:内连接 vs 左 / 右连接
表格
| 连接类型 | 关键字 | 保留数据 | 适用场景 |
|---|---|---|---|
| 内连接 | INNER JOIN | 两张表的交集 | 只查匹配数据 |
| 左外连接 | LEFT JOIN | 左表全部数据 | 以左表为主,查全部 + 关联 |
| 右外连接 | RIGHT JOIN | 右表全部数据 | 以右表为主,查全部 + 关联 |
简单记:
- 要交集 → 内连接
- 要某张表全量数据 → 左 / 右连接
- 左连接 = 左边全显;右连接 = 右边全显
六、实战 OJ 推荐
学完直接练手:
- LeetCode:178. Rank Scores(分数排名)178. 分数排名 - 力扣(LeetCode)
- LeetCode:626. Exchange Seats(换座位)626. 换座位 - 力扣(LeetCode)