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

小林子
小林子
发布时间:2026-10-13 | 4人浏览过
原创

SQL Server 中 SELECT 语句的实际执行顺序与书写顺序截然不同。理解其背后的 11 个逻辑处理步骤及虚拟表(VT)的变化,能有效避免语法错误并提升查询性能。

逻辑查询处理完整流程

在 SQL Server 中,查询处理器遵循特定的逻辑顺序来解析和执行 SQL 语句。每一步都会产生一个虚拟表(Virtual Table),作为下一步骤的输入,直到最后一步返回结果给调用者。若某子句不存在,则跳过相应步骤。

标准执行顺序如下:

  1. (8) SELECT: DISTINCT, <TOP_specification>, <select_list>
  2. (1) FROM: <left_table>
  3. (3) JOIN: <join_type> JOIN <right_table>
  4. (2) ON: <join_condition>
  5. (4) WHERE: <where_condition>
  6. (5) GROUP BY: <group_by_list>
  7. (6) WITH (CUBE | ROLLUP)
  8. (7) HAVING: <having_condition>
  9. (10) ORDER BY: <order_by_list>
  10. (9) DISTINCT
  11. (11) TOP: <select_list>

第一步:FROM - 组装数据源

目的:确定查询的基础数据来源。
操作:对 FROM 子句中的前两个表执行笛卡尔积(交叉连接),生成虚拟表 VT1。如果包含多个表,将重复此过程直至所有表加入。

第二步:ON - 应用联结条件

目的:根据联结条件筛选行。
操作:对 VT1 应用 ON <join_condition>。只有使条件为 TRUE 的行才会被插入到 VT2。对于 OUTER JOIN(如 LEFT JOIN),未找到匹配的行也将作为外部行添加到 VT2,生成 VT3。

第三步:WHERE - 行级过滤

目的:在分组前移除不符合条件的行。
操作:对 VT3 应用 WHERE <where_condition>。只有使条件为 TRUE 的行才被插入 VT4。注意:WHERE 不能包含聚合函数。

第四步:GROUP BY - 分组

目的:将数据划分为多个逻辑组。
操作:按 GROUP BY <group_by_list> 中的列对 VT4 进行分组,生成 VT5。

第五步:HAVING - 组级过滤

目的:基于聚合结果筛选分组。
操作:首先计算表达式(如 SUM, COUNT),然后对 VT5 应用 HAVING <having_condition>。只有使条件为 TRUE 的组才会被插入 VT7(中间经过 CUBE/ROLLUP 生成 VT6)。

第六步:SELECT & DISTINCT - 投影与去重

目的:选择最终展示的列并消除重复。
操作:处理 SELECT 列表,产生 VT8。随后应用 DISTINCT 去除重复行,生成 VT9。

第七步:ORDER BY - 排序与 TOP - 取数

目的:指定结果集顺序并限制行数。
操作:首先将 VT9 按 ORDER BY <order_by_list> 排序,生成有序表 VC10。最后应用 TOP,从 VC10 开头选取指定数量或比例的 rows 作为 VT11 返回。

实战示例分析

假设有一个学生成绩表 tb_Grade,我们需要找出“考生姓名”不为空、且“总成绩”最大值大于 600 分的学生姓名,并按最高分降序排列。

SQL 语句:

SELECT 考生姓名, MAX(总成绩) AS max总成绩
FROM tb_Grade
WHERE 考生姓名 IS NOT NULL
GROUP BY 考生姓名
HAVING MAX(总成绩) > 600
ORDER BY max总成绩 DESC;

执行步骤解析:

  1. FROM: 加载 tb_Grade 全表数据。
  2. WHERE: 筛选出 考生姓名 IS NOT NULL 的记录。
  3. GROUP BY: 按 考生姓名 分组。
  4. 聚合计算: 计算每组的 MAX(总成绩)。
  5. HAVING: 筛选 MAX(总成绩) > 600 的分组。
  6. ORDER BY: 对结果按 max总成绩 排序。
  7. SELECT: 输出最终的列名和值。

优化建议

  • 逻辑清晰性:虽然 SQL 解析器能自动纠正顺序,但按照逻辑执行顺序书写代码能提高可读性和维护性。
  • 性能考量:WHERE 子句应在 GROUP BY 之前使用,以减少需要分组的数据量;JOIN 条件应放在 ON 中而非 WHERE 中(针对外连接时尤为重要)。
  • 避免隐式转换:确保参与比较的数据类型一致,以避免索引失效导致的全表扫描。

以上就是 SQL Server 中 SELECT 语句执行顺序的详细内容,更多关于 SQL 查询优化的资料请关注本站其它相关文章!

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表