怎样在SQL中实现分组后的累计求和_利用窗口函数实现运行总计
为什么GROUP BY不行,而窗口函数可以?
很多朋友一开始会想,既然要分组求和,那直接用GROUP BY不就好了?但仔细一想就发现不对。GROUP BY会把数据“压缩”成每组一行,只给你一个最终的总和。而我们想要的是“分组内的累计和”——它需要保留原始数据中的每一行,并按照入职时间这样的顺序,一行一行地把数值累加起来。这完全是两码事。
免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈
所以,正确的路径是使用窗口函数。它最大的好处就是不改变查询结果的行数,允许你在分组内部再定义一套排序和累积的逻辑,完美契合“运行总计”的需求。

为什么 SUM() 加 GROUP BY 不能直接得到分组内累计和
举个例子,如果你直接写 SELECT dept, SUM(salary) FROM emp GROUP BY dept,得到的结果只是每个部门薪资的总和,而不是我们想要的“按入职时间顺序逐行累加”的运行总计。
这里有个常见的“坑”:很多人会把窗口函数里的ORDER BY漏掉,或者放错位置。记住,这个ORDER BY必须出现在OVER()子句的内部,而且它的顺序必须和你想累计的方向一致。如果漏了,在有些数据库里,结果会直接退化成整组的总和(相当于没起作用);在另一些数据库(比如MySQL 8.0之前的版本)里,甚至可能会直接报错。
SUM() OVER(PARTITION BY ... ORDER BY ...) 的写法要点
标准的写法结构是固定的:SUM(salary) OVER(PARTITION BY dept ORDER BY hire_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)。我们来拆解一下:
PARTITION BY dept:这是划定“战场”的,它告诉数据库,按部门分区,每个部门独立计算自己的累计值,互不干扰。ORDER BY hire_date:这是决定“顺序”的,累计必须有个方向,这里我们按入职时间先后累加。切记,尽量使用业务上确定性的排序字段,避免用id这类可能重复或者无明确业务意义的列。ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW:这是定义“窗口框架”的,意思是“从分区的第一行累加到当前行”。这个子句其实是默认值,可以省略,但显式写出来会让代码意图更清晰。只有当你需要计算滑动窗口(比如包含当前行之后若干行)时,才需要去调整它。
不同数据库对 ORDER BY 的强制要求差异
这一点需要特别注意,不同数据库的“脾气”不一样。像PostgreSQL和SQL Server就比较严格,它们要求窗口函数里只要有聚合,就必须配上ORDER BY,否则直接报错。而MySQL 8.0+和Oracle相对宽松,允许你省略,但结果会退化成组内无序的累计,这个值是不可预测的,基本没用。
所以,最稳妥的实践就是:一律显式写上ORDER BY,这样代码跨数据库迁移时问题最少。
另一个容易踩坑的地方是排序字段的类型。如果你用hire_date这种日期类型,通常没问题。但如果你用salary作为排序依据,当有多条记录的薪资相同时,它们的累计顺序就可能不稳定(在使用ROW_NUMBER()或需要精确对齐的场景下尤其麻烦)。解决办法是追加一个二级排序字段,确保唯一性,比如ORDER BY salary, emp_id。
累计和与累计占比的联动写法
实际业务中,我们经常不仅要累计和,还想知道“当前累计额占本组总和的比例”。这时候,你不能直接嵌套窗口函数(比如SUM(SUM() OVER(...)) OVER(...)这种写法是非法的),而需要借助子查询或者CTE(公共表表达式)来分步计算。
WITH grouped AS (
SELECT dept, salary, hire_date,
SUM(salary) OVER(PARTITION BY dept ORDER BY hire_date) AS running_sum,
SUM(salary) OVER(PARTITION BY dept) AS total_dept
FROM emp
)
SELECT dept, salary, hire_date,
running_sum,
ROUND(running_sum * 100.0 / total_dept, 2) AS pct
FROM grouped;
注意看,计算total_dept(部门总薪资)的窗口定义里,是没有ORDER BY的,所以它返回的是每一行所在部门的固定总和。而running_sum是动态变化的累计值。把这两个值组合起来,才能安全地算出比例。
最后提一个真正麻烦的情况:当分组键本身存在NULL值时。PARTITION BY dept会把所有dept IS NULL的行都归到同一组里。但在大多数业务场景下,我们可能希望把这些空值记录排除掉,或者单独处理。正确的做法是在窗口函数计算之前,就用WHERE dept IS NOT NULL提前过滤掉,不要指望窗口函数自己来处理这个边界问题。
相关攻略
以太网交换机端口VLAN设置:从规划到验证的实战指南 给交换机端口划分VLAN,听起来是基础操作,但配置的精准度直接决定了整个二层网络的“健康”状况。其核心逻辑并不复杂:通过静态方式,将物理端口精准地划归到指定的VLAN ID下,并根据端口所连接设备的不同角色,灵活选用Access、Trunk或Hy
半球电热水壶安装的核心在于确保底座稳固、电气连接可靠、温控机构精准复位 新壶到手,先别急着烧水。安装这事儿,看似简单,实则每一步都关乎安全和后续的使用体验。核心就围绕三点:底座得稳如磐石,电源连接要万无一失,最关键的是那个负责自动断电的温控机构,必须装得精准到位。下面咱们就按顺序,把每一步拆解清楚。
要达到最佳效果,按摩椅必须遵循“科学频次、精准力度、身心协同”的使用原则 想让按摩椅真正成为你的健康伙伴,而不是一件摆设?关键在于掌握一套科学的“使用说明书”。每天早晚各一次、每次20分钟,这个时长可不是凭空而来,而是经过了临床康复研究和主流品牌海量用户实测验证的黄金标准。至于力度调节,必须严格遵从
家用投影仪不仅适合小户型,而且正成为现代紧凑型居住空间的理想影音解决方案 谁说小空间就与影院级享受无缘?如今,像当贝D6X Pro这样的新一代机型,正凭借其2 1kg的轻巧机身、1 2:1的友好投射比,以及能灵活旋转225度的AI云台,彻底改写了游戏规则。你只需大约3米的距离,就能轻松投出81英寸的
是的,半球电热水壶在首次使用前必须清洗 这几乎是所有正规家电产品启用前的“规定动作”。你可能会想,新买的水壶看起来光洁如新,为什么还要多此一举?原因在于,即便是采用食品级304不锈钢内胆和智能蒸汽感应控温技术的合规产品,在经历生产、仓储和运输的漫长旅程后,内胆表面仍可能附着微量的金属加工碎屑、防锈保
热门专题
热门推荐
2026年4月2日,一场始于订单的“双向奔赴” 汽车圈最近上演了一出颇有温度的品牌互动,起因是一张来自社交平台的购车订单。一位原奥迪车主公开晒出了小米SU7的订单截图,并向相关负责人致以问候。这原本只是一条个人动态,却没承想,引发了一连串超出预期的友好回应。 消息传出后,上汽奥迪的反应堪称迅速且巧妙
特斯拉2026年Q1财报解读:业绩稳健增长,自动驾驶与机器人战略加速落地 2026年第一季度,特斯拉再次向市场展示了其强劲的发展动能。在全球电动汽车市场,特斯拉产量成功突破40 8万辆,实现同比12 7%的稳健增长;同期交付量达到35 8万辆,同比增长6 5%。与此同时,特斯拉储能业务表现突出,总装
四月一日,沙盒游戏我的世界推出一次特别更新,引发广泛关注 话说回来,四月的第一天,经典沙盒游戏《我的世界》,就整了个“大活儿”。一项听起来颇有碘伏性的设计调整,在社区内炸开了锅:游戏直接移除了沿用已久的仓库系统,改为所有物品都能随手放在地面,想用的时候捡起来就行。 仓库功能向来是此类建造型游戏的核心
巨鲸再出手:千万美元级ETH悄然离场 市场总是静水深流。就在今天,链上数据捕捉到一笔值得玩味的动向。根据链上分析师Onchain Lens的监测,大约三小时前,一个地址尾号为“24d4”的巨鲸,从知名交易所Kraken一口气提取了4,472枚ETH。按当前市价估算,这笔资产价值接近一千万美元。 这可
京东京造再推黄金配件新品:磁吸支架以亲民价格亮相 关注京东京造的朋友一定还记得此前推出的黄金手机壳,因其独特设计与高纯度金材质引发了不少讨论。如今品牌再度升级,带来了一款更贴近日常使用的“轻量化”黄金配件——黄金气囊手机磁吸支架,进一步降低了黄金数码配件的入手门槛。 产品解析:含金量与设计亮点 这款





