【问题标题】:reset a running total in same partition based on a condition根据条件重置同一分区中的运行总计
【发布时间】:2023-04-05 15:44:01
【问题描述】:

今天使用 sum over partition 计算各组的总和非常容易。

我需要根据条件重置同一分区中的总计,如果一行中的某些字段为假,则应重置总和并从该行开始。 在代码中这很容易,只需遍历行并检查条件。但是我们如何在 SQL 中实现呢?

这是一个示例,它包含一个包含四个字段的表,以及一个汇总运行金额的查询。如果 ResetSum 字段为真,则应重置总和。

CREATE TABLE dbo.Table_1
(
PersonID int NOT NULL,
Amount money NOT NULL,
PayDate date NOT NULL,
ResetSum bit NOT NULL
)

INSERT INTO Table_1 (PersonID, Amount, PayDate, ResetSum) 
VALUES  (1, 100, '2015-1-1', 0)
,(1,200,'2015-1-2',0)
,(1,180,'2015-1-3',0)
,(1,200,'2015-1-4',1)
,(1,200,'2015-1-5',0)
,(1,360,'2015-1-6',0)

SELECT *,SUM(Amount) over(PARTITION BY PersonID ORDER BY PayDate) as SumAmount
FROM Table_1 

期望的结果应该是 760,而不是 1140。

ResetSum 字段不能对记录进行分组,因为如果为真,则该行下的所有字段都应重置,尽管该行中的 ResetField 为假。

这是我的 .net 代码示例,非常简单:

    Public Function SumTest() As Decimal
    Dim lst As New List(Of TestRecords)
    Dim sum As Decimal = 0
    For Each tst As TestRecords In lst
        If tst.ResetSum = true Then
            sum = fcf.Amount
        Else
            sum += fcf.Amount
        End If
    Next
    Return sum
End Function

【问题讨论】:

  • 请发布您尝试过的任何代码。

标签: sql-server-2012 sum


【解决方案1】:

在派生表中对ResetSum 进行运行总计,并将其用作Amount 上运行总计中的分区列。

select T.PersonID,
       T.Amount,
       T.PayDate,
       sum(T.Amount) over(partition by T.PersonID, T.ResetSum 
                          order by T.PayDate rows unbounded preceding) as SumAmount
from (
     select T1.PersonID,
            T1.Amount,
            T1.PayDate,
            sum(case T1.ResetSum 
                  when 1 then 1 
                  else 0 
                end) over(partition by T1.PersonID 
                          order by T1.PayDate rows unbounded preceding) as ResetSum
     from dbo.Table_1 as T1
     ) as T;

SQL Fiddle

【讨论】:

  • 好主意。但是没有子查询就没有更直接的方法吗?
  • @IFink 看看你得到的执行计划。它尽可能笔直。您可能可以使用递归 CTE 来做到这一点,但我认为您不会发现该版本更简单。
  • 你说得对,这很好。我的问题更多是希望 ssms 在 over 子句中添加这样的选项。我接受你的回答。
猜你喜欢
  • 2018-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-20
  • 2020-10-16
  • 2021-03-27
  • 2021-09-22
相关资源
最近更新 更多