当前位置: 首页
数据库
如何用SQL嵌套查询实现累计求和(无窗口函数)

如何用SQL嵌套查询实现累计求和(无窗口函数)

热心网友 时间:2026-06-25
转载

利用自连接条件(如a id>=b id)分组后对b表数值求和,即可模拟累计求和,适用于无窗口函数的MySQL5 7等旧版本。排序字段需唯一(如id),重复时需额外唯一主键兜底以保证顺序。

自连接模拟累计求和,简单说就是针对当前行,把所有排序位置不大于它的记录数值累加起来。这要求有一个明确的排序字段(比如idorder_date),而且该字段最好是唯一的——一旦出现重复值,就必须再搬一个唯一主键出来兜底排序。在MySQL 5.7这类没有窗口函数的旧版本里,这招是通用做法。

如何通过SQL嵌套查询在没有窗口函数的情况下实现累计求和?

用自连接模拟累计求和的原理

没有窗口函数时,累计求和本质上是:对当前行,把所有满足“排序位置 ≤ 当前行”的记录的数值加起来。通过JOIN把表和自身按顺序条件关联就能实现——比如按时间或ID排序后,左表的每行去匹配右表中“ID小于等于它”的所有行。

关键点很明确:必须有唯一的排序字段(如idorder_date),且值不能重复,否则会多算;如果实在避免不了重复,就得搭配额外的唯一字段(比如自增主键)做保底排序。

MySQL 5.7 / PostgreSQL 9.5 等旧版本实操写法

假设有一张销售表sales,含字段id(递增)、amount(单笔金额),目标是按id顺序计算累计金额:

SELECT s1.id, s1.amount,       SUM(s2.amount) AS cumulative_amountFROM sales s1JOIN sales s2 ON s2.id <= s1.idGROUP BY s1.id, s1.amountORDER BY s1.id;

这里有三点需要注意:

  • GROUP BY必须包含所有非聚合列(s1.id, s1.amount),否则MySQL 5.7+的严格模式会报错Expression #2 of SELECT list is not in GROUP BY clause
  • 如果id不连续(比如删过数据),逻辑上不影响,只影响“顺序”是否符合业务预期。
  • 性能会随着数据量增长急剧下降——N行输入大约引发N²次比较,数据量上万就要警惕了。

处理重复时间戳或并列排序的补救方法

当排序依据是order_date且存在多条同一天记录时,直接写s2.order_date <= s1.order_date会导致同天数据互相全量累加,结果偏大。

稳妥的做法是引入唯一辅助排序字段(比如自增id):

SELECT s1.id, s1.amount, s1.order_date,       SUM(s2.amount) AS cumulative_amountFROM sales s1JOIN sales s2   ON s2.order_date < s1.order_date   OR (s2.order_date = s1.order_date AND s2.id <= s1.id)GROUP BY s1.id, s1.amount, s1.order_dateORDER BY s1.order_date, s1.id;

这个条件拆成两部分:小于日期 + 等于日期但 id 更小或相等,确保严格保序。

Oracle 11g 或 SQL Server 2008 的兼容性提醒

上述写法在这些数据库里基本可用,但要注意:

  • SQL Server对JOIN条件中的不等式(<=)支持良好,但若表没有索引,执行计划容易走嵌套循环,速度会非常慢。
  • Oracle中如果用ROWNUM伪列替代id,行不通——ROWNUM是结果集生成时才分配的,无法用于自连接中的稳定排序依据。
  • 所有场景下,务必给排序字段建索引,例如CREATE INDEX idx_sales_order_date_id ON sales(order_date, id);

真正麻烦的是数据量超过10万行还硬扛这种写法——这会儿已经不是语法问题了,是得去说服业务方接受分页累计,或者升级数据库版本,用SUM() OVER (ORDER BY ...)彻底解放生产力。

来源:https://www.php.cn/faq/2665747.html

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

同类文章
更多
为什么SQL中 NOT IN 子查询遇到 NULL 会导致 JOIN 逻辑完全崩溃失效

为什么SQL中 NOT IN 子查询遇到 NULL 会导致 JOIN 逻辑完全崩溃失效

SQL的NOTIN子查询若结果包含NULL,三值逻辑会使整行判断为UNKNOWN,WHERE仅保留TRUE,导致所有行被过滤,返回空集。推荐使用NOTEXISTS替代,它不比较值,只判断子查询是否返回行,天然规避NULL问题。LEFTJOIN+ISNULL易写错,COALESCE或加ISNOTNULL仅权宜之计,可能掩盖数据问题。

时间:2026-07-21 06:28
完整Redis集群架构图及搭建步骤详解,新手必看

完整Redis集群架构图及搭建步骤详解,新手必看

一、简介 Redis集群功能从3 0版本开始引入,到5 0 14版本已经相当成熟。本文就来聊聊如何搭建一个最简单的集群,以及常用的集群管理命令。版本锁定在5 0 14,所有操作均基于此版本。 二、架构图 先来看一个最基础的集群架构,一目了然: 三、搭建集群 3 1、下载 这里是在一台Linux服务器

时间:2026-07-21 06:28
SQL存储过程结合XML数据类型的高性能解析技巧

SQL存储过程结合XML数据类型的高性能解析技巧

直接用 nodes() + value(),别碰 OPENXML 从 SQL Server 2005 起,OPENXML 就应该被淘汰了。它需要手动调用 sp_xml_preparedocument 和 sp_xml_removedocument,一旦遗漏后者就会引发内存泄漏;而且整个过程基于临

时间:2026-07-21 06:28
SQL窗口函数生成带层级结构的财务流水号技巧

SQL窗口函数生成带层级结构的财务流水号技巧

财务流水号按业务类型分组连续编号,需用ROW_NUMBER()OVER(PARTITIONBYbusiness_typeORDERBYcreate_time)生成,避免先GROUPBY致明细丢失。日期前缀和补零拼接需注意数据库差异。多级嵌套结构需在PARTITIONBY中增加额外分类字段,并发环境下窗口函数无法保证唯一性,需结合序列或锁机制。

时间:2026-07-21 06:27
SQL中COALESCE函数优雅处理NULL值技巧与最佳实践全面指南

SQL中COALESCE函数优雅处理NULL值技巧与最佳实践全面指南

COALESCE函数从左到右返回首个非NULL值,参数顺序决定兜底是否生效;类型不兼容时PostgreSQL和SQLServer报错,需显式CAST对齐;运算前需对每个可能为NULL的项单独包裹,否则表达式整体为NULL;避免在WHERE或JOIN条件中使用,否则导致语义错乱或索引失效;不处理空字符串,需嵌套NULLIF。

时间:2026-07-21 06:27
热门专题
更多
刀塔传奇破解版无限钻石下载大全 刀塔传奇破解版无限钻石下载大全
洛克王国正式正版手游下载安装大全 洛克王国正式正版手游下载安装大全
思美人手游下载专区 思美人手游下载专区
好玩的阿拉德之怒游戏下载合集 好玩的阿拉德之怒游戏下载合集
不思议迷宫手游下载合集 不思议迷宫手游下载合集
百宝袋汉化组游戏最新合集 百宝袋汉化组游戏最新合集
jsk游戏合集30款游戏大全 jsk游戏合集30款游戏大全
宾果消消消原版下载大全 宾果消消消原版下载大全
  • 热门数据榜