Skip to content

SQL SELECT 语句逻辑执行顺序详解 ​

💡 核心理念

与大多数编程语言按编码顺序处理代码不同,SQL 是一种声明式语言,其处理顺序与书写顺序大相径庭。理解 SQL 的逻辑执行顺序是编写高效查询、解决复杂 Join 和聚合问题的基础。


1. 逻辑执行顺序概览 ​

虽然我们在编写 SQL 时以 SELECT 开头,但数据库引擎首先处理的是数据源(FROM)。

1.1 标准执行序列 ​

  1. FROM: 组装数据源。
  2. ON: 应用联接筛选器。
  3. JOIN: 处理关联表(如 LEFT JOIN 补齐外部行)。
  4. WHERE: 对记录行进行初次筛选。
  5. GROUP BY: 将数据划分为多个分组。
  6. AGGREGATIONS: 执行聚合函数计算。
  7. HAVING: 筛选分组结果。
  8. SELECT: 确定返回的字段。
  9. DISTINCT: 行去重。
  10. ORDER BY: 对结果集进行排序。
  11. TOP / OFFSET-FETCH: 截取指定数量的行。

2. 逻辑查询处理阶段详解 ​

在 SQL Server 中,每个步骤都会产生一个虚拟表 (Virtual Table, VT),该表作为下一步骤的输入。

步骤子句处理逻辑产出
Step 1FROM对前两个表执行笛卡尔积(交叉联接)。VT1
Step 2ON对 VT1 应用 ON 筛选器,仅保留满足条件的行。VT2
Step 3OUTER JOIN如果是外部联接,将保留表中未匹配的行作为外部行添加回 VT2。VT3
Step 4WHERE对 VT3 应用 WHERE 筛选器,过滤掉不符合条件的记录。VT4
Step 5GROUP BY按指定的列对 VT4 中的行进行分组。VT5
Step 6CUBE / ROLLUP如果指定了超组运算,则生成相应的汇总行。VT6
Step 7HAVING对分组后的 VT6 应用筛选器。VT7
Step 8SELECT处理选择列表,计算表达式,提取最终字段。VT8
Step 9DISTINCT移除 VT8 中的重复行。VT9
Step 10ORDER BY根据指定的列对 VT9 进行排序,产生游标(而非表)。VC10
Step 11TOP从 VC10 的起始处截取指定行数。VT11

3. 关键知识点与避坑指南 ​

🔴 别名的可用性 由于 SELECT 在 WHERE 和 GROUP BY 之后执行,因此在 WHERE 子句中无法使用 SELECT 中定义的列别名。

🟡 WHERE 与 HAVING 的区别

  • WHERE 作用于 GROUP BY 之前,过滤的是原始行。
  • HAVING 作用于 GROUP BY 之后,过滤的是聚合后的分组。

🟢 性能优化启示 尽量在 WHERE 阶段过滤掉尽可能多的数据,以减小后续 GROUP BY 和 JOIN 操作的虚拟表体积。


✅ 执行顺序简记口诀

FROM -> ON -> JOIN -> WHERE -> GROUP BY -> HAVING -> SELECT -> DISTINCT -> ORDER BY -> TOP


🔗 参考资料

方舟 · Ark