MySQL 视频课 · 50 集 / 子查询:标量、列、行、表子查询 / P47

第 47 集 / 共 50 · 子查询:标量、列、行、表子查询 · 视频 p=47 · 时长 7:05

P47 47. 基础-多表查询-表子查询

讲义 5.6.5 表子查询 p84–85

按主题对应,非逐句切分

来源与核对说明

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

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

讲义索引:p84–85 · 5.6.5 表子查询 · 切点 notexact

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

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

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

表子查询返回多行多列,可以当成一张临时表。课程里用整行 IN 来匹配;放进 FROM 时,它就是派生表。

画面采样未覆盖结尾:最远采样点 5:39 / 全片 7:05;结尾段相关表述仅依据标题与已采画面,属主题级核实。

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

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

一句话理解

表子查询返回多行多列。整行匹配用 (列1,列2) IN (子查询);放进 FROM 当派生表时,MySQL 8 要求必须起别名。

跟播:视频里 ↔ 本站

视频里 / 原课字段本站对应
emp / deptemployee / department
派生表必须起别名(如 e)同左(MySQL 8 强制要求)

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

按这 4 步做

  1. 先看内层是不是多行多列。多行多列不能用 =,也不能按单列思维写,要把外层对应的几列用括号打包,整行去比。
  2. 列的顺序和数量要对齐。(dept_id, salary) IN (SELECT dept_id, MAX(salary) ...) 左边两列,内层也必须两列、同顺序。
  3. 放进 FROM 时它就是派生表。外层只能看到它 SELECT 出来的列,而且必须写 AS t;MySQL 8 不给别名报 ERROR 1248。
  4. 能改写就改写,但先确认等价:表子查询换成 JOIN + GROUP BY 之前,先想清楚会不会因为一对多把行数放大、会不会丢掉 NULL 分组;改完用同一份数据对一遍行数和结果。想比快慢就看实际执行计划(EXPLAIN),别凭“JOIN 一定更快”下结论——数据量、索引和优化器都会变。

小例

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

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

-- 每行是“本部门最高工资”,整行匹配
SELECT id, name, dept_id, salary
FROM employee
WHERE (dept_id, salary) IN (
  SELECT dept_id, MAX(salary)
  FROM employee
  GROUP BY dept_id
);

-- 同一类结果放进 FROM,就是派生表(必须起别名)
SELECT t.dept_id, t.avg_salary
FROM (
  SELECT dept_id, AVG(salary) AS avg_salary
  FROM employee
  WHERE dept_id IS NOT NULL
  GROUP BY dept_id
) AS t
WHERE t.avg_salary > 9000;

第一段内层给出两个组合:(1,10000)、(2,12000),还有一组 (NULL,NULL) 因为小李没部门;IN 匹配不上 NULL,所以外层 2 行:小周、小陈。第二段派生表先算平均,研发部 9000、测试部 12000,外层筛大于 9000,只剩 2 号部门 1 行。 两段的共同点只是“内层都返回多行多列”:第一段拿每部门最高工资做整行匹配,第二段拿每部门平均工资当派生表再筛,聚合不同、行集也不同,不能互换;相同的是“多行多列可以当集合用 IN,也可以当表放 FROM”这个用法区别。先判断你要筛行,还是要再算一层。

易错点

30 秒速记

表子查询=多行多列;整行 IN 匹配;也能当 FROM 派生表;派生表必须起别名。

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

自测 1:表子查询和列子查询的区别?

列子查询一列多行,用 IN 比单值;表子查询多行多列,要按整行匹配或当派生表。

自测 2:派生表在 MySQL 8 不给别名会怎样?

报 ERROR 1248,每张派生表都必须有别名。

自测 3:派生表和临时表是一回事吗?

不是;派生表只在当前查询内存在,查询结束就没了,也不是真实建表。

材料与来源

展开材料出处、讲义页码与证据等级
材料类型 / 位置支持了什么
BV1Kr4y1i7ru P47(平台标题)平台视频页 · P47静帧 t=212s 显示“表子查询”标题与 (job,salary) IN (SELECT job,salary ...) 的整行匹配示例
MySQL 8.0 Reference Manual — Subqueries官方文档仅用于核对子查询语义与错误码,不是课程材料

本集无逐字稿(匿名 player/v2 返回 subtitles=[]、need_login_subtitle=true),并以讲义公开镜像讲义 5.6.5 表子查询(p84–85)核对章节与主题;画面静帧只用于确认场景,不是内容边界。示例表与数据为本笔记自建,不是课程原表;不含原始帧或字幕。 本课把多行多列子查询称表子查询,示例用整行 IN;FROM 派生表与别名要求为同主题补充说明。

讲义对照:讲义 5.6.5 表子查询 · p84–85(公开镜像;按主题对应,切点 notexact)

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

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

下载本集 Markdown