# P22 22. 基础-SQL-DQL-执行顺序

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

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

## P22 22. 基础-SQL-DQL-执行顺序

- 原视频：https://www.bilibili.com/video/BV1Kr4y1i7ru/?p=22（p=22），时长 7:57
- 讲义：2.6.9 执行顺序 p49–50（公开镜像；按主题对应，切点 notexact）

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

### 一句话理解

SQL 的书写顺序和执行顺序不是一回事：你从 SELECT 开始写，数据库却先找表、再筛行、再分组，最后才挑列。

### 步骤

1. FROM：先确定数据来自哪张表，这是第一步。
2. WHERE：对行做过滤，此时 SELECT 里的别名还不存在。
3. GROUP BY 分堆、HAVING 筛堆；聚合值到这一步才算出来。
4. SELECT 取出要显示的列，然后 ORDER BY 排序、LIMIT 截断。

### SQL 示例

```
SELECT id, name, salary * 12 AS 年薪
FROM employee
WHERE salary IS NOT NULL
ORDER BY 年薪 DESC;
```

说明：【原创演示】四行练习数据里小李没有薪资，WHERE 先把他去掉；SELECT 用 salary*12 算出年薪并起别名，ORDER BY 才能直接用“年薪”。结果三行：小陈 144000、小周 120000、小林 96000。若把条件换成 WHERE 年薪 > 90000 会直接报错（Unknown column），因为 WHERE 阶段别名还没生成。

### 易错点

- 以为 SELECT 写在最前面就先执行，于是在 WHERE 里用别名：会报未知列。
- 把 HAVING 当 WHERE 用：能在 WHERE 做的行过滤不要拖到 HAVING，语义不同还白算一遍分组。
- 把这套顺序当成引擎真实的指令流水线：它是解释“别名、聚合能写在哪”的逻辑顺序，优化器实际怎么取数另说。

### 30 秒速记

书写：SELECT→FROM→WHERE→GROUP BY→HAVING→ORDER BY→LIMIT；理解：FROM→WHERE→GROUP BY→HAVING→SELECT→ORDER BY→LIMIT。

### 自测

1. ORDER BY 能用 SELECT 里的别名，WHERE 不能，为什么？
   - 答：按逻辑顺序 WHERE 在 SELECT 之前执行，那时别名还没被定义；ORDER BY 排在 SELECT 之后，所以能引用。
2. 为什么说“执行顺序”不等于引擎的指令序列？
   - 答：它是 SQL 语义的分层理解方式，用来判断每个子句能看到什么；真实执行由优化器决定访问路径和顺序，可能合并或跳过步骤。

### 材料与来源

- [平台视频页] P22 原视频页（BV1Kr4y1i7ru） https://www.bilibili.com/video/BV1Kr4y1i7ru/?p=22
- [官方文档] MySQL 8.0 Reference：SELECT 语句 https://dev.mysql.com/doc/refman/8.0/en/select.html

证据说明：按 t20 帧核对：幻灯片“DQL-执行顺序”左侧黄色框是编写顺序 SELECT/FROM/WHERE/GROUP BY/HAVING/ORDER BY/LIMIT，红圈数字可见 FROM=1、WHERE=2、GROUP BY=3、SELECT=4；该帧是动画中间态，HAVING/ORDER BY/LIMIT 的编号未出现，完整顺序按 SQL 标准语义补全，并已在正文说明这是逻辑理解顺序而非引擎指令序列。无字幕。
