根据条件重置同一分区中的运行总计

IFi*_*ink 3 sum sql-server-2012

如今,使用 sum over partition可以非常轻松地对组进行总计。

我需要根据条件重置同一分区中的总计,如果一行中的某些字段为假,则应重置总和并从该行开始。在代码中这非常简单,只需循环行并检查条件即可。但是我们如何在 SQL 中实现这一点呢?

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

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 
Run Code Online (Sandbox Code Playgroud)

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

记录不能按 ResetSum 字段进行分组,因为如果该字段为 true,则尽管该行中的 ResetField 为 false,但下面的所有字段都应重置。

这是我的 .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
Run Code Online (Sandbox Code Playgroud)

Mik*_*son 5

在派生表中执行运行总计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;
Run Code Online (Sandbox Code Playgroud)

SQL小提琴