SQL 聚合函数和窗口函数怎么结合使用?

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

SQL 聚合函数和窗口函数怎么结合使用?

SQL 聚合函数和窗口函数怎么结合使用?

SQL中的聚合函数用于对一组数据进行计算并返回单个结果,比如求和、计数、求平均值等,通常会配合GROUP BY子句对数据进行分组统计,分组后每组只会返回一条汇总结果。窗口函数则是在保持原有数据行数的基础上,对每一行数据进行计算,计算结果会关联到对应的行上,不会减少返回的行数。两者结合使用可以在同一条查询中同时实现分组汇总和明细行展示的需求,不需要多次查询再关联,大幅提升查询效率。

聚合函数与窗口函数的基础特性对比

先明确两者的核心差异,才能更好地理解结合使用的逻辑:

特性聚合函数窗口函数
返回结果行数分组后每组1行与原始数据行数一致
常用语法配合GROUP BY使用配合OVER(PARTITION BY)使用
典型用途数据汇总统计分组内排序、分组内排名、分组内累计计算

两者结合使用的常见场景

场景一:查询明细数据时同时展示分组汇总值

比如我们需要查询每个员工的工资明细,同时需要知道该员工所在部门的总工资、平均工资,不需要先分组统计部门工资再和员工表关联。这时候可以先把聚合函数作为窗口函数使用,在OVER子句中指定分组逻辑即可。

假设有员工表emp,字段包含emp_id(员工ID)、dept_id(部门ID)、salary(工资),示例查询代码如下:

-- 查询员工明细,同时展示部门总工资、部门平均工资
SELECT
  emp_id,
  dept_id,
  salary,
  -- 聚合函数SUM作为窗口函数,按部门分组计算总工资
  SUM(salary) OVER(PARTITION BY dept_id) AS dept_total_salary,
  -- 聚合函数AVG作为窗口函数,按部门分组计算平均工资
  AVG(salary) OVER(PARTITION BY dept_id) AS dept_avg_salary
FROM emp;

场景二:分组聚合后做二次窗口计算

有时候我们需要先对数据做分组聚合,得到每个分组的汇总结果,再对这些汇总结果做窗口计算,比如计算每个部门的总工资在所有部门中的排名。这时候可以先通过子查询或者CTE完成分组聚合,再在外层查询中使用窗口函数。

同样以emp表为例,查询每个部门的总工资和该总工资在所有部门中的排名:

-- 先分组聚合得到部门总工资,再计算排名
WITH dept_salary AS (
  -- 第一步:用聚合函数分组统计部门总工资
  SELECT
    dept_id,
    SUM(salary) AS total_salary
  FROM emp
  GROUP BY dept_id
)
-- 第二步:对部门总工资用窗口函数计算排名
SELECT
  dept_id,
  total_salary,
  RANK() OVER(ORDER BY total_salary DESC) AS salary_rank
FROM dept_salary;

场景三:聚合函数与专用窗口函数配合完成复杂统计

比如我们需要查询每个员工的工资,同时知道部门内工资排名,以及部门总工资、部门内工资累计值。这时候可以同时使用聚合类窗口函数和专用窗口函数比如ROW_NUMBER、SUM的累计写法。

示例代码如下:

SELECT
  emp_id,
  dept_id,
  salary,
  -- 专用窗口函数,计算部门内工资排名
  ROW_NUMBER() OVER(PARTITION BY dept_id ORDER BY salary DESC) AS dept_salary_rank,
  -- 聚合函数作为窗口函数,计算部门总工资
  SUM(salary) OVER(PARTITION BY dept_id) AS dept_total_salary,
  -- 聚合函数作为窗口函数,计算部门内工资累计值(按工资降序累计)
  SUM(salary) OVER(PARTITION BY dept_id ORDER BY salary DESC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS dept_cum_salary
FROM emp;

结合使用的注意事项

  • 不要在同一个SELECT子句中同时使用普通聚合函数和GROUP BY,又同时使用窗口函数,除非窗口函数的OVER子句中不包含和GROUP BY冲突的逻辑,否则会报语法错误。
  • 聚合函数作为窗口函数使用时,不需要配合GROUP BY子句,分组逻辑写在OVER的PARTITION BY中即可。
  • 窗口函数的执行顺序在WHERE、GROUP BY、HAVING之后,所以如果需要对聚合后的结果做窗口计算,建议用子查询或者CTE先完成聚合,再进行窗口计算。
  • 如果聚合函数作为窗口函数时OVER子句中没有PARTITION BY,那么会对全表数据做聚合计算,每一行都会返回同一个全表汇总值。

总结

SQL聚合函数和窗口函数的结合使用核心在于理解两者的定位:聚合函数负责数据汇总,窗口函数负责在明细行上关联计算规则。结合使用的场景主要分为两类,一类是把聚合函数作为窗口函数直接在OVER子句中指定分组,实现明细带分组汇总的需求;另一类是先用聚合函数分组得到汇总结果,再对汇总结果用窗口函数做二次计算。掌握这种结合用法可以减少不必要的表关联,提升复杂查询的开发效率和执行性能。

SQL聚合函数窗口函数查询优化修改时间:2026-06-20 01:54:33

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