sql-servercumulative-sumwindowingfiscal

Using SQL Server windowing function to get running total by fiscal year


I'm using SQL Server 2014. I have a Claims table containing totals of claims made per month in my system:

+-----------+-------------+------------+
| Claim_ID  | Claim_Date  | Nett_Total |
+-----------+-------------+------------+
| 1         | 31 Jan 2012 |  321454.67 |
| 2         | 29 Feb 2012 |  523542.34 |
| 3         | 31 Mar 2012 |   35344.33 |
| 4         | 30 Apr 2012 |  142355.63 |
| etc.      | etc.        | etc.       |
+-----------+-------------+------------+

For a report I am writing I need to be able to produce a cumulative running total that resets to zero at the start of each fiscal year (in my country this is from March 1 to February 28/29 of the following year).

The report will look similar to the table, with an extra running total column, something like:

+-----------+-------------+------------+---------------+
| Claim_ID  | Claim_Date  | Nett_Total | Running Total |
+-----------+-------------+------------+---------------+
| 1         | 31 Jan 2012 |  321454.67 |     321454.67 |
| 2         | 29 Feb 2012 |  523542.34 |     844997.01 |
| 3         | 31 Mar 2012 |   35344.33 |      35344.33 | (restart at 0
| 4         | 30 Apr 2012 |  142355.63 |     177699.96 |  for new yr) 
| etc.      | etc.        | etc.       |               |
+-----------+-------------+------------+---------------+

I know windowing functions are very powerful and I've used them in rudimentary ways in the past to get overall sums and averages while avoiding needing to group my resultset rows. I have an intuition that I will need to employ the 'preceding' keyword to get the running total for the current fiscal year each row falls into, but I can't quite grasp how to express the fiscal year as a concept to use in the 'preceding' clause (or if indeed it's possible to use a date range in this way).

Any assistance on the way of "phrasing" the fiscal year for the "preceding" clause will be of enormous help to me, please.


Solution

  • i think you should try this:

    /* Create Table*/
    CREATE TABLE dbo.Claims (
     Claim_ID int
    ,Claim_Date datetime
    ,Nett_Total decimal(10,2)
    );
    
    /* Insert Testrows*/
    INSERT INTO dbo.Claims VALUES 
     (1, '20120101', 10000)
    ,(2, '20120202', 10000)
    ,(3, '20120303', 10000)
    ,(4, '20120404', 10000)
    ,(5, '20120505', 10000)
    ,(6, '20120606', 10000)
    ,(7, '20120707', 10000)
    ,(8, '20120808', 10000)
    

    Query the Data:

    SELECT  Claim_ID, Claim_Date, Nett_Total, SUM(Nett_Total) OVER
    (PARTITION BY YEAR(DATEADD(month,-2,Claim_Date)) ORDER BY Claim_ID) AS
    [Running Total] FROM dbo.Claims
    

    The Trick: PARTITION BY YEAR(DATEADD(month,-2,Claim_Date))

    New Partition by year, but i change the date so it fits your fiscal year.

    Output:

    Claim_ID |Claim_Date                 |Nett_Total  |Running Total
    ---------+---------------------------+------------+-------------
    1        |2012-01-01 00:00:00.000    |10000.00    |10000.00
    2        |2012-02-02 00:00:00.000    |10000.00    |20000.00
    3        |2012-03-03 00:00:00.000    |10000.00    |10000.00   <- New partition
    4        |2012-04-04 00:00:00.000    |10000.00    |20000.00
    5        |2012-05-05 00:00:00.000    |10000.00    |30000.00
    6        |2012-06-06 00:00:00.000    |10000.00    |40000.00
    7        |2012-07-07 00:00:00.000    |10000.00    |50000.00
    8        |2012-08-08 00:00:00.000    |10000.00    |60000.00