30 day moving sum using the OVER clause in SQL server 2012

1.9k Views Asked by At

I am trying to write a view in SQL Server 2012 where I calculate the 30 day moving sum for a set of transactions.

Current script:

SELECT CustNo, TransactionDate, TransactionAmount, SUM(TransactionAmount) 
        OVER (PARTITION BY CustNo ORDER BY TransactionDate) AS MovingAmount
FROM         dbo.TransactionData

Data set:

 CustNo     TransactionDate    TransactionAmount
 1111       5/7/2015           3,000
 1111       5/14/2015          3,000
 2222       5/17/2015          100
 1111       5/21/2015          3,000
 1111       5/28/2015          3,000
 3333       5/31/2015          11,000
 1111       6/10/2015          3,000

Expected Result:

 CustNo     TransactionDate    TransactionAmount   MovingAmount
 1111       5/7/2015           3,000               12,000 
 1111       5/14/2015          3,000               12,000
 2222       5/17/2015          100                 100
 1111       5/21/2015          3,000               9,000
 1111       5/28/2015          3,000               6,000
 3333       5/31/2015          11,000              11,000
 1111       6/10/2015          3,000               3,000  

Other attempts:

SELECT CustNo, TransactionDate, TransactionAmount, SUM(TransactionAmount) 
        OVER (PARTITION BY CustomerNumber ORDER BY TransactionDate, 
        BETWEEN TransactionDate AND DATEADD(day, 30, TransactionDate)) 
        AS MovingAmount
FROM         dbo.TransactionData
1

There are 1 best solutions below

4
Zohar Peled On

I'm assuming the 12,000 in the first row of your desired result is a typo, and it should be 3,000. If I'm correct, your first query seems to be working fine, it's just hard to see without an order by to the entire query:

Create and populate sample table (Please save us this step in your future questions)

CREATE TABLE TransactionData 
(
    CustNo int,
    TransactionDate date,
    TransactionAmount int
)

INSERT INTO TransactionData(CustNo, TransactionDate, TransactionAmount) VALUES
(1111, '2015-05-07', 3000),
(1111, '2015-05-14', 3000),
(2222, '2015-05-17', 100),
(1111, '2015-05-21', 3000),
(1111, '2015-05-28', 3000),
(3333, '2015-05-31', 11000),
(1111, '2015-06-10', 3000)

Going with Tab Alleman's interpretation of the question, It can't be done with the over clause, you need to use a correlated sub query:

SELECT  CustNo, 
        TransactionDate, 
        TransactionAmount, 
        (SELECT SUM(TransactionAmount) 
         FROM dbo.TransactionData t1 
         WHERE t1.CustNo = t0.CustNo
         AND t1.TransactionDate >= t0.TransactionDate
         AND t1.TransactionDate <= DATEADD(DAY, 30, t0.TransactionDate)) As MovingAmount
FROM dbo.TransactionData t0
ORDER BY CustNo, TransactionDate

Results:

CustNo  TransactionDate         TransactionAmount   MovingAmount
1111    07.05.2015 00:00:00     3000                12000
1111    14.05.2015 00:00:00     3000                12000
1111    21.05.2015 00:00:00     3000                9000
1111    28.05.2015 00:00:00     3000                6000
1111    10.06.2015 00:00:00     3000                3000
2222    17.05.2015 00:00:00     100                 100
3333    31.05.2015 00:00:00     11000               11000

You can see a live demo on rextester.