# P46 46. 基础-多表查询-行子查询

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

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

## P46 46. 基础-多表查询-行子查询

- 原视频：https://www.bilibili.com/video/BV1Kr4y1i7ru/?p=46（p=46），时长 4:36
- 讲义：5.6.4 行子查询 p83–84（公开镜像；按主题对应，切点 notexact）

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

### 一句话理解

行子查询返回一行多列，用括号把几个字段凑成一行去比：(salary, manager_id) = (子查询)。

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

视频用「和张无忌薪资、直属领导都相同」演示行子查询。

| 视频里 / 原课字段 | 本站对应 |
|---|---|
| (salary, managerid) | (salary, manager_id) |
| emp 17 行 | employee 4 行 |

看完应能：会用括号把多列凑成一行去比较，并知道含 NULL 时整行比较会失效

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

### 步骤

1. 先想清楚为什么要凑成一行。分成 salary = (...) AND manager_id = (...) 两个子查询，两个值可能来自不同的人，逻辑就错了；行比较保证同属一行。
2. 括号里的列顺序要一致。左边先 salary 后 manager_id，子查询也必须这个顺序；反了通常不报错，只是永远不相等。
3. 确认子查询只返回一行。行构造器配 = 时多行直接报 ERROR 1242；要多行匹配得换成 IN，那是下一页的表子查询。 行构造器不是万能元组比较，列数、类型都要严格对上。

### SQL 示例

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

-- 与 3 号员工“工资 + 上级”都相同的人
SELECT id, name, salary, manager_id
FROM employee
WHERE (salary, manager_id) = (
  SELECT salary, manager_id FROM employee WHERE id = 3
);
```

说明：内层按主键查到一行 (12000, 2)，外层逐行比较两个值是否同时相等，只有小陈自己，1 行。把条件换成 id = 2 会得到 (10000, NULL)：NULL 参与行比较结果未知，连小周自己都匹配不上——这是行子查询最隐蔽的坑。 行比较的语义是“同时相等”，不是“任一相等”；要任一相等得拆成 OR，别硬套行构造器。

### 易错点

- 行里任一列为 NULL，整行比较为 unknown，永远不相等；要匹配 NULL 用 <=> 或拆开写 IS NULL。
- 左右列数或顺序不一致，可能不报错但结果恒空，先逐列对齐。
- 多行结果不能用 =，报 ERROR 1242，改用 IN。
- (a,b) = (SELECT a FROM ...) 列数不匹配会报 ERROR 1241，先数括号里的列。

### 30 秒速记

行子查询=一行多列；括号列序对齐；= 只接一行；NULL 让整行比较失效；多行换 IN。

### 自测

1. (salary, manager_id) = (子查询) 里子查询返回 2 行会怎样？
   - 答：报 ERROR 1242；多行比较要用 IN。
2. manager_id 为 NULL 的那行能被 = 匹配吗？
   - 答：不能，整行比较为 unknown；用 <=> 或分别处理 NULL。
3. 为什么不能把行子查询拆成两个独立子查询？
   - 答：两个子查询各自取值，可能来自不同行，拼出来的组合根本不存在。

### 材料与来源

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

证据说明：本集无逐字稿（匿名 player/v2 返回 subtitles=[]、need_login_subtitle=true），并以讲义公开镜像讲义 5.6.4 行子查询（p83–84）核对章节与主题；画面静帧只用于确认场景，不是内容边界。示例表与数据为本笔记自建，不是课程原表；不含原始帧或字幕。 题干只取“同薪资同上级”这一主题，示例与数据为自建。
