导读:本期聚焦于小伙伴创作的《SQL如何计算分组内的百分比占比?窗口函数聚合功能详解》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《SQL如何计算分组内的百分比占比?窗口函数聚合功能详解》有用,将其分享出去将是对创作者最好的鼓励。

在数据分析的实际工作中,计算分组内的百分比占比是非常常见的需求,比如统计不同产品类别的销量占全品类总销量的比例、不同地区的用户数占全平台用户数的比例等。这类需求如果用传统的SQL写法,往往需要先统计分组总和,再统计总体总和,最后通过子查询或者表关联完成计算,步骤繁琐且性能不佳。窗口函数的出现让这类计算变得简单高效,它可以在保留原表所有行的基础上,对指定窗口内的数据进行聚合计算,非常适合处理分组占比类的需求。

SQL如何计算分组内的百分比占比?窗口函数聚合功能详解

窗口函数基础概念

窗口函数也叫OLAP函数,它会对一组相关行执行计算,同时不会将多行合并成单行,这和普通的聚合函数有本质区别。普通聚合函数比如SUM()COUNT()会把分组内的多行数据合并成一行结果,而窗口函数会在每一行都返回一个计算结果,原表的行数不会发生变化。

窗口函数的基本语法结构如下:

函数名(参数) OVER (
    [PARTITION BY 分组列]
    [ORDER BY 排序列 [ASC|DESC]]
    [窗口帧定义]
)

其中PARTITION BY用来指定分组的列,作用类似GROUP BY,但不会合并行;ORDER BY用来指定窗口内数据的排序规则;窗口帧定义可以指定计算的范围,不过计算分组占比时通常不需要额外设置。

计算分组内百分比占比的核心思路

要计算分组内的百分比占比,核心逻辑是:先通过窗口函数计算出每个分组的总和,再计算出所有数据的总和,最后用分组总和除以所有数据的总和得到占比。具体步骤如下:

  • 第一步:用SUM(目标列) OVER(PARTITION BY 分组列)计算每个分组的总和,得到分组维度的聚合值
  • 第二步:用SUM(目标列) OVER()计算所有数据的总和,这里没有PARTITION BY,窗口就是整个数据集
  • 第三步:用分组总和除以总体总和,再乘以100得到百分比,最后可以根据需要保留小数位数

实际案例演示

假设我们有一张销售数据表sales_data,表结构如下:

列名类型说明
departmentVARCHAR部门名称
productVARCHAR产品名称
sales_amountINT销售额

现在需要统计每个部门的销售额占全公司总销售额的百分比,具体实现SQL如下:

SELECT
    department,
    SUM(sales_amount) AS dept_total_sales, -- 部门总销售额
    SUM(sales_amount) OVER() AS company_total_sales, -- 全公司总销售额
    -- 计算占比,保留2位小数,乘以100得到百分比
    ROUND(SUM(sales_amount) * 100.0 / SUM(sales_amount) OVER(), 2) AS sales_percent
FROM sales_data
GROUP BY department;

上面的查询中,SUM(sales_amount) OVER()没有指定PARTITION BY,所以窗口是整个表,计算的是全公司的总销售额。然后先按部门分组计算每个部门的销售额总和,再用部门总和除以公司总和得到占比。

如果还需要同时展示每个产品的销售额占部门销售额的百分比,不需要额外分组,直接用窗口函数即可:

SELECT
    department,
    product,
    sales_amount,
    -- 产品销售额占部门销售额的百分比
    ROUND(sales_amount * 100.0 / SUM(sales_amount) OVER(PARTITION BY department), 2) AS dept_percent
FROM sales_data;

这里SUM(sales_amount) OVER(PARTITION BY department)会计算每个部门内的销售额总和,然后用单条产品的销售额除以部门总和,就得到了该产品在部门内的销售占比,原表的所有行都会保留,不需要GROUP BY

注意事项

在使用窗口函数计算百分比时,需要注意几个问题:

  • 除法计算时要保证分子或者分母至少有一个是浮点型,否则整数除法会得到整数结果,比如上面的100.0就是为了保证计算结果是浮点型,得到准确的百分比小数
  • 如果数据中存在NULL值,SUM函数会自动忽略NULL,如果需要把NULL当作0处理,可以用COALESCE(列名, 0)包裹目标列
  • 不同数据库对窗口函数的支持略有差异,主流的MySQL 8.0+、PostgreSQL、SQL Server、Oracle都支持标准窗口函数语法,低版本数据库可能无法使用
窗口函数除了计算分组占比,还可以实现排名、前后行取值、移动平均等多种分析功能,是SQL进阶学习中非常重要的内容,掌握后可以大幅提升复杂查询的编写效率。

SQL窗口函数分组百分比聚合函数数据分析修改时间:2026-07-22 06:48:26

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