Sql 如何使用SUM和OVER在Oracle中获取运行总计

Sql 如何使用SUM和OVER在Oracle中获取运行总计,sql,oracle,oracle12c,Sql,Oracle,Oracle12c,我使用Sum()Over(Partition by…Order by…)函数来计算一列的运行总数,但每当值重复(或重复)时就会出现问题。Sum()over似乎按值对它们进行分组,并将所有按值分组的总和作为移动和。这不是我想要达到的。对于为什么它会以一组重复值的形式发生,以及如何在不按等级进行游标循环的情况下实现正确的运行总数,我们深表感谢。下面是测试表及其数据的详细信息,以及附加一个具有预期结果的文件(附加文件中突出显示的列是Oracle Sum()计算不正确的内容) 我使用的查询“计算我的跑步

我使用Sum()Over(Partition by…Order by…)函数来计算一列的运行总数,但每当值重复(或重复)时就会出现问题。Sum()over似乎按值对它们进行分组,并将所有按值分组的总和作为移动和。这不是我想要达到的。对于为什么它会以一组重复值的形式发生,以及如何在不按等级进行游标循环的情况下实现正确的运行总数,我们深表感谢。下面是测试表及其数据的详细信息,以及附加一个具有预期结果的文件(附加文件中突出显示的列是Oracle Sum()计算不正确的内容)

我使用的查询“计算我的跑步总数”如下所示-

SELECT A1,A2,A2SUBCLASS,DENSERNK,A2CONTRI,
SUM(A2CONTRI) OVER (PARTITION BY A1,A2SUBCLASS,DENSERNK ORDER BY A2CONTRI 
asc) AS RUNTOTA2CONTRI
FROM RUNNINGTOTAL_TEST1
ORDER BY A2SUBCLASS ASC;


问题是关于Oracle的,下面我的答案是基于DB2OLAP实现的——它有不同的默认值。有关正确的Oracle语法,请参见@mathguy的答案

如果你想要一个运行总和,除了在你想要运行总和“span”的范围内,不要使用partition by,然后它将按照order by part排序,在这个问题中,这是无效的或不够具体的,现在还不清楚你使用的是什么排序--我在下面做了一个猜测--应该是接近的

SELECT A1,A2,A2SUBCLASS,DENSERNK,A2CONTRI,
  SUM(A2CONTRI) OVER (ORDER BY DESNSERNK, A2, A2CONTRI) AS RUNTOTA2CONTRI
FROM RUNNINGTOTAL_TEST1
ORDER BY A2SUBCLASS ASC;

问题是关于Oracle的,下面我的答案是基于DB2OLAP实现的——它有不同的默认值。有关正确的Oracle语法,请参见@mathguy的答案

如果你想要一个运行总和,除了在你想要运行总和“span”的范围内,不要使用partition by,然后它将按照order by part排序,在这个问题中,这是无效的或不够具体的,现在还不清楚你使用的是什么排序--我在下面做了一个猜测--应该是接近的

SELECT A1,A2,A2SUBCLASS,DENSERNK,A2CONTRI,
  SUM(A2CONTRI) OVER (ORDER BY DESNSERNK, A2, A2CONTRI) AS RUNTOTA2CONTRI
FROM RUNNINGTOTAL_TEST1
ORDER BY A2SUBCLASS ASC;

默认情况下,分析函数使用范围窗口指令(见下文-默认为第一个版本)。您要查找的是ROWS指令(见下文),它不是默认的,因此必须显式地包含它

RANGE windowing子句(默认值)与您注意到的完全一样:它将所有“并列”行视为“包含在总和中”

添加:链接到文档


默认情况下,分析函数使用范围窗口指令(见下文-默认为第一个版本)。您要查找的是ROWS指令(见下文),它不是默认的,因此必须显式地包含它

RANGE windowing子句(默认值)与您注意到的完全一样:它将所有“并列”行视为“包含在总和中”

添加:链接到文档


你是如何排序这个答案的?我想你不明白SUM是什么——它是分区的总和,不是一个运行的总和。谢谢你的回答。我是按A2Contri字段排序的,该字段用于导出运行总数。我并不反对你的观点,并认为我可能没有正确地使用Sum函数来推导运行总数,但目的是通过子类创建运行总数,因此我使用了partition子句。对于一个新的子类(字段A2Subclass),Denserank将重置为1,因此,对于每个新的A2Subclass值,运行总数将从新开始。@Hogan-这是错误的。解析和与OP认为的完全一样。只有在函数的分析子句中省略ORDER BY子句(这是有效的,但它只是选项之一)时,才能得到分区的总数。你如何对这个答案排序?我想你不明白SUM是什么——它是分区的总数,而不是运行的总和。谢谢你的回答。我是按A2Contri字段排序的,该字段用于导出运行总数。我并不反对你的观点,并认为我可能没有正确地使用Sum函数来推导运行总数,但目的是通过子类创建运行总数,因此我使用了partition子句。对于一个新的子类(字段A2Subclass),Denserank将重置为1,因此,对于每个新的A2Subclass值,运行总数将从新开始。@Hogan-这是错误的。解析和与OP认为的完全一样。只有在函数的分析子句中省略ORDER BY子句(这是有效的,但它只是选项之一)时,才能得到分区的总数。这也没有给出正确的运行总数。我打算在名为Densernk的字段上对具有相同A2子类的A2的所有值进行排序。每次a2子类更改时,我的Densernk将重置为1,并且运行总数将作为新值计算。我希望我能在这篇评论中添加一个jpeg文件,但我会尝试添加到原始帖子中。谢谢你的帮助!!非常感谢…@Hogan-你什么意思?每个分区内的运行和是绝对有效的,并且使用解析和函数、按分区和按顺序精确计算。OP代码中唯一的问题是windowing子句,它应该使用。。。(默认值为介于…之间的范围,该范围与OP报告的范围完全相同)。我建议你删除这个答案,因为它可能会误导那些不熟悉分析函数的人(比如你自己)。@mathguy--我重新写了我的答案,以正确的方式指出他们可能被误解,但是你的评论似乎有点不真实,因为你在回答中没有使用分区,这正是我要说的。在DB2(我可以在其上进行测试)中,默认值与您描述的不同,这将很好地工作。我认为你不应该建议人们删除他们的答案。。。它是。。好。。。说得好。。。。不礼貌的。您可以选择将我的答案标记为,并查看其他人是否认为应该将其删除。@Hogan-分区从来都不是问题,我在回复中故意不使用它,因为它与问题无关-唯一的问题是ha
with test_data ( x ) as (
       select  10 from dual union all
       select  20 from dual union all
       select  30 from dual union all
       select  30 from dual union all
       select  30 from dual union all
       select 100 from dual
     )
select x
     , sum(x) over (order by x range between unbounded preceding and current row) range_sum
     , sum(x) over (order by x rows  between unbounded preceding and current row) rows_sum
from   test_data
order by x;

         X  RANGE_SUM   ROWS_SUM
---------- ---------- ----------
        10         10         10
        20         30         30
        30        120         60
        30        120         90
        30        120        120
       100        220        220