MySQL 视频课 · 50 集 / 多表查询:多表关系、内/外/自连接、联合查询 / P40

第 40 集 / 共 50 · 多表查询:多表关系、内/外/自连接、联合查询 · 视频 p=40 · 时长 7:27

P40 40. 基础-多表查询-外连接

讲义 5.4 外连接 p77–78

按主题对应,非逐句切分

来源与核对说明

以同版讲义的公开镜像核对章节与页码(镜像非官方出品);非逐字稿,示例为原创补充。

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

讲义索引:p77–78 · 5.4 外连接 · 切点 notexact

讲义是第三方公开镜像(95 页 PDF),不是官方原件;这里只用它核对章节顺序与页码,不转载正文。

完整来源说明与变更记录 →

看视频,对照阅读:在新标签打开原视频(p=40) · 先看跟播对照

外连接解决“配不上的行也要留下”的问题。左连接保左表,右连接保右表,另一边补 NULL。

复习模式:快速跳知识点(详解在下方各节)

复习顺序:先看“一句话理解”能否复述,再扫步骤,最后做自测;答不出时回到小例与易错。

一句话理解

外连接在内连接的基础上,保留某一侧“配不上”的行,另一侧补 NULL。

跟播:视频里 ↔ 本站

视频里 / 原课字段本站对应
讲义里没有部门的是陈友谅(dept_id 为空)本站是小李(dept_id 为空),左连接后部门列是 NULL
emp LEFT JOIN deptemployee LEFT JOIN department(写法相同)

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

按这 4 步做

  1. 先想清楚要保住谁。要“所有员工,包括没部门的”,员工在左就用 LEFT JOIN;要“所有部门,包括没人的”,部门放右边用 RIGHT JOIN。
  2. ON 里写连接条件,也可以写“只影响能不能配上”的过滤。过滤放 ON 还是 WHERE,取决于你想保留哪些左行:想保留全部员工、只给研发部的人标上部门,就把 d.name = '研发部' 放 ON,其他员工照样出现、部门列是 NULL;只要研发部员工,就把条件放 WHERE(或者干脆用内连接)。两者是不同的问题,不是对错。判断办法:把条件从 ON 挪到 WHERE,如果连本来没配上的左行也一起消失,说明这个过滤本身在筛员工,不只是筛匹配。
  3. 验证时数行数:左连接保证左表每一行至少出现一次,所以结果行数不会少于左表行数;本例 department.id 是主键、一名员工最多配上一个部门,结果才恰好 4 行。若左表一行配上多个右表行,行数变多(4 行变 5 行以上)是正常放大,不是写错;变成 3 行才说明有左行被过滤掉了。
  4. 统计时要分清 COUNT(*) 和 COUNT(右表列):前者数结果行,后者只数真正匹配上的行。

小例

先准备本集练习数据:p40.sql · 练习库说明

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

SELECT e.name AS 员工, d.name AS 部门
FROM employee e
LEFT JOIN department d ON e.dept_id = d.id
ORDER BY e.id;

SELECT e.name AS 员工, d.name AS 部门
FROM employee e
RIGHT JOIN department d ON e.dept_id = d.id
ORDER BY d.id;

左连接 4 行,第 4 行是“小李 / NULL”,因为他的 dept_id 为空;本例 department.id 是主键,一名员工最多配一个部门,所以没有一对多放大,行数才正好等于左表的 4 行。右连接换方向保部门,也是 4 行,最后一行“NULL / 运营部”,因为运营部还没人。想让运营部那行出现在“部门在左”的写法里,把表序换成 department LEFT JOIN employee 即可。 右连接也可以调换表序写成 LEFT JOIN,结果相同;团队里通常统一用 LEFT,方向更一致。

易错点

30 秒速记

左保左、右保右;配不上补 NULL;过滤放 ON 还是 WHERE 看要保留哪些左行;COUNT(*)≠COUNT(右表列)。

自测(3 题,先答再展开)

自测 1:左连接后想只留“没有部门的员工”,条件怎么写?

WHERE d.id IS NULL(或 d.name IS NULL),写在连接之后。

自测 2:LEFT JOIN 结果 4 行,COUNT(*) 和 COUNT(d.id) 分别是?

4 和 3;COUNT(列) 不数 NULL。

自测 3:为什么 LEFT JOIN 之后再写 d.id IS NOT NULL 会变回内连接?

它把补出来的 NULL 行全部滤掉,剩下的就是匹配行,结果与内连接相同。

材料与来源

展开材料出处、讲义页码与证据等级
材料类型 / 位置支持了什么
BV1Kr4y1i7ru P40(平台标题)平台视频页 · P40静帧 t=89s 为“连接查询-外连接”标题页;t=178s 显示左外/右外两道题的注释
MySQL 8.0 Reference Manual — JOIN Clause官方文档仅用于核对连接语义与错误码,不是课程材料

本集无逐字稿(匿名 player/v2 返回 subtitles=[]、need_login_subtitle=true),并以讲义公开镜像讲义 5.4 外连接(p77–78)核对章节与主题;画面静帧只用于确认场景,不是内容边界。示例表与数据为本笔记自建,不是课程原表;不含原始帧或字幕。

讲义对照:讲义 5.4 外连接 · p77–78(公开镜像;按主题对应,切点 notexact)

  • 画面静帧 9 帧,采样点 0:12–7:13 / 全片 7:27(只用于确认画面主题,不作内容边界)
  • 原声字幕未取得:匿名接口字幕轨为空且需登录,未使用任何账号

等级含义:平台视频页 / 官方文档 / 课件 = 原始材料;二手整理 = 参考;推断 = 未经核实。站内补充的解释与练习会在此说明。

下载本集 Markdown