SQL SELECT如何结合窗口函数实现复杂数据查询?

来源:站长站作者:广州SEO公司头衔:草根站长
导读:本期聚焦于小伙伴创作的《SQL SELECT如何结合窗口函数实现复杂数据查询?》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《SQL SELECT如何结合窗口函数实现复杂数据查询?》有用,将其分享出去将是对创作者最好的鼓励。

SQL中的窗口函数能够在查询结果集的基础上,对数据进行分组内的计算分析,不会改变原结果集的行数,非常适合处理排名、累计值、前后行对比等场景,结合SELECT语句使用时可以大幅简化复杂查询的逻辑。

SQL SELECT如何结合窗口函数实现复杂数据查询?

窗口函数的基本语法结构

SELECT结合窗口函数使用时,核心结构是在SELECT的字段列表中加入窗口函数表达式,窗口函数通过OVER子句来定义窗口范围,基本语法如下:

SELECT 
    列1,
    列2,
    窗口函数(参数) OVER (
        [PARTITION BY 分区列]
        [ORDER BY 排序列 [ASC|DESC]]
        [ROWS|RANGE 窗口框架]
    ) AS 别名
FROM 表名;

其中OVER子句里的三个部分都是可选的,根据实际需求选择使用即可。

PARTITION BY 分区的作用

PARTITION BY用来将数据按照指定列分成多个独立的分组,窗口函数会在每个分组内独立计算,效果类似GROUP BY但不会合并行。比如我们需要统计每个部门内的员工薪资排名,就可以用部门列作为分区条件。

ORDER BY 排序的作用

ORDER BY用来指定每个分区内数据的排序规则,很多排名类窗口函数必须依赖排序规则才能正确计算结果,比如ROW_NUMBER()RANK()等函数都需要明确排序字段。

常用的窗口函数分类

结合SELECT使用的窗口函数主要分为三类,不同类型的函数适用场景有所区别。

排名类窗口函数

这类函数用来在分区内对数据进行排名,常见的有三个:

  • ROW_NUMBER():给每一行分配一个唯一的连续序号,即使排序值相同也会分配不同的序号
  • RANK():排序值相同时会分配相同的排名,下一个排名会跳过重复的数量
  • DENSE_RANK():排序值相同时分配相同排名,下一个排名不会跳过重复的数量

以下是一个统计员工部门内薪资排名的示例:

SELECT 
    emp_id,
    dept_name,
    salary,
    ROW_NUMBER() OVER (PARTITION BY dept_name ORDER BY salary DESC) AS row_num,
    RANK() OVER (PARTITION BY dept_name ORDER BY salary DESC) AS rank_val,
    DENSE_RANK() OVER (PARTITION BY dept_name ORDER BY salary DESC) AS dense_rank_val
FROM employee;

聚合类窗口函数

普通的聚合函数如SUM()AVG()COUNT()等,加上OVER子句之后就可以作为窗口函数使用,用来计算每个分区内的累计值、平均值等,不会合并行。

比如统计每个员工的薪资以及所在部门的平均薪资:

SELECT 
    emp_id,
    dept_name,
    salary,
    AVG(salary) OVER (PARTITION BY dept_name) AS dept_avg_salary
FROM employee;

取值类窗口函数

这类函数用来获取当前行前后指定行的数据,常见的有LAG()LEAD()

  • LAG(列, 偏移量, 默认值):获取当前行之前指定偏移量的行的列值
  • LEAD(列, 偏移量, 默认值):获取当前行之后指定偏移量的行的列值

示例为获取每个员工的上一个入职员工的薪资:

SELECT 
    emp_id,
    hire_date,
    salary,
    LAG(salary, 1, 0) OVER (ORDER BY hire_date) AS prev_emp_salary
FROM employee;

窗口框架的使用

OVER子句中还可以通过ROWSRANGE指定窗口框架,用来限定每个分区内参与计算的数据行范围,常见的用法有:

  • ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW:从分区第一行到当前行
  • ROWS BETWEEN 3 PRECEDING AND 1 PRECEDING:当前行前3行到前1行
  • ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING:从当前行到分区最后一行

比如计算累计薪资的示例:

SELECT 
    emp_id,
    hire_date,
    salary,
    SUM(salary) OVER (
        ORDER BY hire_date 
        ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
    ) AS cumulative_salary
FROM employee;

使用注意事项

在使用SELECT结合窗口函数时,需要注意以下几点:

  • 窗口函数只能出现在SELECT子句和ORDER BY子句中,不能出现在WHERE、GROUP BY、HAVING子句里
  • 如果同时使用了GROUP BY,窗口函数会在GROUP BY聚合之后的结果集上进行计算
  • 不同数据库对窗口函数的支持程度略有差异,比如MySQL从8.0版本开始才支持窗口函数,使用前需要确认数据库版本
窗口函数的执行顺序在WHERE、GROUP BY、HAVING之后,在SELECT的普通字段计算之后、ORDER BY之前,理解执行顺序有助于避免逻辑错误。

SQLSELECT窗口函数over_clauserank修改时间:2026-06-20 15:30:28

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