SQL窗口函数执行顺序是怎样的_理解SQL处理与优化逻辑

来源:建站作者:不吃香菜头衔:草根站长
导读:本期聚焦于小伙伴创作的《SQL窗口函数执行顺序是怎样的_理解SQL处理与优化逻辑》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《SQL窗口函数执行顺序是怎样的_理解SQL处理与优化逻辑》有用,将其分享出去将是对创作者最好的鼓励。

SQL窗口函数是处理复杂聚合、排序场景的重要工具,它的执行顺序和常规SQL子句的执行逻辑紧密相关,理解这个顺序能帮助我们写出正确的查询语句,也能为SQL优化提供方向。

SQL窗口函数执行顺序是怎样的_理解SQL处理与优化逻辑

SQL语句的完整标准执行顺序

一条完整的SQL查询语句,从解析到返回结果,会按照固定的阶段依次处理,标准执行顺序如下:

  • FROM:确定查询的数据源,包括表连接操作
  • ON:处理表连接的条件
  • JOIN:完成表连接,生成临时结果集
  • WHERE:过滤临时结果集的行
  • GROUP BY:对结果集按指定列分组
  • 聚合函数计算:执行COUNT、SUM等聚合函数的计算
  • HAVING:过滤分组后的结果
  • SELECT:选择需要返回的列,此时窗口函数会在这个阶段执行
  • DISTINCT:对结果去重
  • ORDER BY:对最终结果排序
  • LIMIT:限制返回的行数

窗口函数的具体执行时机

窗口函数的执行发生在SELECT子句处理阶段,也就是在WHERE、GROUP BY、HAVING这些过滤和分组操作完成之后才会执行。这意味着窗口函数计算时,能拿到已经经过前期过滤、分组后的最终结果集,不会受到后续ORDER BY、LIMIT子句的影响。

需要注意的是,窗口函数不会像GROUP BY那样把多行合并成一行,它会为每一行返回一个计算结果,结果行数和输入行数保持一致。

示例验证执行顺序

我们创建一个员工表作为示例,表结构如下:

-- 创建员工表
CREATE TABLE employee (
    id INT PRIMARY KEY,
    dept VARCHAR(20),
    salary INT
);

-- 插入测试数据
INSERT INTO employee VALUES
(1, '研发部', 8000),
(2, '研发部', 10000),
(3, '市场部', 7000),
(4, '市场部', 9000),
(5, '研发部', 12000);

执行以下查询语句,观察窗口函数的执行效果:

SELECT 
    dept,
    salary,
    -- 窗口函数:计算部门内薪资排名
    RANK() OVER (PARTITION BY dept ORDER BY salary DESC) AS dept_salary_rank
FROM employee
WHERE salary > 7500
ORDER BY dept, dept_salary_rank;

这个查询的执行流程是:

  1. FROM employee:加载员工表全部数据
  2. WHERE salary > 7500:过滤掉薪资小于等于7500的行,此时id为3的员工(薪资7000)会被过滤掉
  3. SELECT子句处理:先选择dept、salary列,再执行RANK()窗口函数,按dept分区、薪资降序排名,此时参与计算的是过滤后的4行数据
  4. ORDER BY dept, dept_salary_rank:对窗口函数计算后的结果排序,返回最终结果

最终查询结果如下:

deptsalarydept_salary_rank
研发部120001
研发部100002
研发部80003
市场部90001

基于执行顺序的优化思路

理解窗口函数的执行顺序后,我们可以从以下几个方向优化SQL查询:

提前过滤数据减少窗口函数计算量

因为窗口函数在WHERE之后执行,所以尽量把能提前过滤的条件放到WHERE子句中,减少参与窗口函数计算的行数,提升执行效率。比如上面的例子中,先过滤掉薪资低的员工,再计算部门排名,比先算排名再过滤效率更高。

避免在窗口函数中做不必要的复杂计算

窗口函数的计算是针对每一行进行的,如果窗口函数里的逻辑过于复杂,会明显增加执行耗时。如果可以在前期预处理的计算,不要放到窗口函数里处理。

合理选择窗口范围

如果只需要计算部分行的聚合结果,比如最近3行的平均值,可以通过ROWS BETWEEN 2 PRECEDING AND CURRENT ROW这样的子句限制窗口范围,减少不必要的计算。

常见误区说明

很多开发者会误以为窗口函数可以在WHERE子句中使用,实际上因为窗口函数在SELECT阶段才执行,WHERE阶段还没有窗口函数的计算结果,所以不能在WHERE里引用窗口函数的别名或者结果。如果需要根据窗口函数的结果过滤,需要把查询作为子查询,在外层使用WHERE过滤:

SELECT *
FROM (
    SELECT 
        dept,
        salary,
        RANK() OVER (PARTITION BY dept ORDER BY salary DESC) AS dept_salary_rank
    FROM employee
) t
WHERE dept_salary_rank = 1;

这个查询先在内层子查询中计算排名,外层再过滤排名第一的员工,是符合执行顺序的正确写法。

SQL窗口函数SQL执行顺序SQL优化窗口函数用法修改时间:2026-06-10 01:39:29

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。