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)
在派生表中执行运行总计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)
| 归档时间: |
|
| 查看次数: |
3562 次 |
| 最近记录: |