# P48 48. 基础-多表查询-练习1

> 本页是学习笔记，不等同于视频逐字稿。原声字幕未取得（匿名接口字幕轨为空且需登录，未使用任何账号），也没有逐句讲解记录；讲义只按节与页码对应，切点未逐句确证。

> 以同版讲义的公开镜像核对章节与页码（镜像非官方出品）；非逐字稿，示例为原创补充。

## P48 48. 基础-多表查询-练习1

- 原视频：https://www.bilibili.com/video/BV1Kr4y1i7ru/?p=48（p=48），时长 17:42
- 讲义：5.7 多表查询案例（第 1–4 题所在段） p85–86（公开镜像；按主题对应，切点 notexact）

- 本集练习数据：practice/p48.sql（先执行，再对照小例）

### 一句话理解

把前几页连起来用：先判断“要哪些行”，再选内连接还是外连接，最后检查有没有重复、有没有漏掉无部门的人。

### 跟播：视频里 ↔ 本站

视频在「5.7 多表查询案例」上逐题写：第 1 题隐式、第 2 题显式 + age<30、第 3 题去重、第 4 题外连接。

| 视频里 / 原课字段 | 本站对应 |
|---|---|
| 讲义 emp 17 行 / dept 6 行 | 本站 employee 4 行 / department 3 行（原创小表） |
| emp.job、emp.entrydate | 本页小表没有这两列，题目里也不问 |

看完应能：看到「显式内连接 + 年龄过滤」能立刻写出 INNER JOIN … ON … WHERE age < 30

看视频时以讲义表为准，跟练时用本站表；结构相同、数字不同。

### 步骤

1. 逐题先写“表 + 连接条件 + 过滤条件”三行草稿。表是 employee 和 department，连接条件是 e.dept_id = d.id，过滤条件才决定内连接还是外连接。
2. 题目说“所有员工，没有部门也要”就选 LEFT JOIN；说“有员工的部门”就用内连接再去重。两类题的外连接方向相反，先抓关键词。
3. 写完数行数对答案：4 名员工里 3 人有部门，3 个部门里 2 个有人。题1 和题2 都是内连接，区别是题2 多一个年龄过滤，所以题2 行数更少（1 行对 3 行）；两题行集合不同，不能互相对照。

### SQL 示例

```
-- 表：department(1 研发部, 2 测试部, 3 运营部)
-- employee：小林22/研发8000/上级2，小周25/研发10000/无上级，小陈30/测试12000/上级2，小李21/无部门/NULL/上级2
-- 建表与插入语句见本页练习脚本 p48.sql（独立练习库，跑一次就有这两张表）

-- 题1：所有员工及其部门（隐式内连接），3 行
SELECT e.name AS 员工, e.age AS 年龄, d.name AS 部门
FROM employee e, department d
WHERE e.dept_id = d.id
ORDER BY e.id;

-- 题2：年龄小于 25 的员工及其部门（显式内连接；25 是本页自定，原课是 age < 30），1 行
SELECT e.name AS 员工, e.age AS 年龄, d.name AS 部门
FROM employee e
INNER JOIN department d ON e.dept_id = d.id
WHERE e.age < 25
ORDER BY e.id;

-- 题3：有员工的部门（内连接 + 去重）
SELECT DISTINCT d.id, d.name
FROM employee e, department d
WHERE e.dept_id = d.id;

-- 题4：所有员工及其部门，没部门也要出现
SELECT e.name AS 员工, e.age AS 年龄, d.name AS 部门
FROM employee e
LEFT JOIN department d ON e.dept_id = d.id
ORDER BY e.id;
```

说明：题1 是隐式内连接，4 名员工里只有 3 人有部门（小李 dept_id 为空，配不上），得到 3 行：小林、小周、小陈。题2 在本页是「显式内连接 + age < 25」：年龄小于 25 的有小林 22 和小李 21，小李没部门被内连接去掉，所以只剩 1 行小林——这就是题2 比题1 少的原因，两题行集合不同，不能互相对照。题3 得到 2 行：1 研发部、2 测试部；运营部没人所以不出现；DISTINCT 是因为研发部有两名员工，不去重会重复两行。题4 得到 4 行，小李的部门列是 NULL。 题2 里的 age < 25 是过滤员工，放在 WHERE；如果改成左连接再把它挪进 ON，年龄大的员工仍会出现，只是部门为 NULL，行数就多了。说明：题2 是本页自己的原创练习（显式内连接 + age < 25），不是视频原题逐字；原课第 2 题是「年龄小于 30 岁」+ 显式内连接（讲义 p85 第 2 题），第 1 题才是隐式连接且不带年龄条件，别混着对答案。

### 易错点

- 题3 忘了 DISTINCT，部门会按员工人数重复。
- 题4 “所有员工”却用了内连接，会漏掉小李且不报错。
- 把 e.age 之类的员工过滤写进 ON，左连接仍保留全部员工，含义容易混：连接条件放 ON，过滤员工放 WHERE。

### 30 秒速记

先草稿三行：表、连接条件、过滤；见“所有”用外连接；有员工的部门=内连接+去重；用行数对答案。

### 自测

1. 为什么题3 要 DISTINCT？
   - 答：研发部有两名员工，连接后部门行会重复；DISTINCT 按整行去重。
2. 题4 若把 LEFT 改成 INNER，结果几行？
   - 答：3 行，小李因为 dept_id 为 NULL 被丢掉。
3. 题4 结果里小李的部门列是什么？
   - 答：NULL；LEFT JOIN 保留了他，但 department 里没有对应行。

### 材料与来源

- [平台视频页] BV1Kr4y1i7ru P48（平台标题） https://www.bilibili.com/video/BV1Kr4y1i7ru/?p=48
- [官方文档] MySQL 8.0 Reference Manual — JOIN Clause https://dev.mysql.com/doc/refman/8.0/en/join.html

证据说明：本集无逐字稿（匿名 player/v2 返回 subtitles=[]、need_login_subtitle=true），依据平台标题、讲义 p85–86「5.7 多表查询案例」与公开静帧核对，属主题级核实。示例表与数据为本笔记自建，不是课程原表；不含原始帧或字幕。 题干按同类题型重写；题2 用 age < 25 + 显式内连接，原课第 2 题是 age < 30 + 显式内连接，本页没有照抄原题。
