Menu

Dynamic calculations of running totals

A few weeks back, a friend from South Africa wrote to me asking if I knew of a way to quickly produce cumulative totals from monthly data figures. Here is one way to achieve just that. As the fiscal year at his firm begins in July and ends at the end of June, the trick was to first obtain the data in tabular form with the first fiscal month on top and the last in the bottom row. (See the first grid below).

The raw data within the grid comes from his data warehouse and the result set stored within a local temporary table, to be used to calculate the running totals.

The ‘YearMth’ column is not hardwired but derived from the year under consideration. I shall blog how this was achieved in an upcoming posting.

To the astute reader, the ‘YearMth’ column is used as a sort field and never appears in any of his reports. The calendar month is shown in its stead.

The result set from the ‘summing’ of items count and dollar revenue BY month may be seen in the table below:

YearMth

Month

Item Count

Dollar Revenue

201207

July

4

122

201208

August

3

12

201209

September

3

143

201210

October

6

66

201211

November

6

88

201212

December

5

77

201301

January

7

321

201302

February

7

465

201303

March

6

876

201304

April

15

906

201305

May

8

756

201306

June

4

32

Coming from both a SQL Server and Oracle world, I can see where the naughty word CURSOR can be a double edged sword. To the ‘doubting Thomas’ out there, there IS a time and place for cursors.

Considering that the data source for my cursor was stored in a temporary table and that the number of records extracted were less than 50000 rows, I took the plunge and used a CURSOR to calculated the running total.

Getting the job done

The first task was to define a table variable @DollarTable. This table defined the 5 fields (YearMth, Month, Item Count , Dollar Revenue and Cumulative, 4 of which we observed in the grid above.

We then define a few more local variables @YearMth, @Month,@ItemCount,@DollarRevenue,@RunningTotal (as may be seen in the code below). These variables are used within the cursor.

@RunningTotal will be the variable associated with the cumulative totals. See the code snippet below.

FETCH NEXT FROM rt_cursor INTO @YearMth,@Month,@ItemCount,@DollarRevenue

END

CLOSE rt_cursor

DEALLOCATE rt_cursor

SELECT * into #rawdata9 FROM @DollarTable

The reader will note that @RunningTotal had been initalized to 0. We now open our cursor (as a transaction) to read the first record from our local temporary data table and WHILE there are records to FETCH, we loop through the records.

The first task is to set @RunningTotal to the value of @RunningTotal (0 on the first pass) to @RunningTotal + the DollarRevenue of the first record.

With each subsequent pass, @RunningTotal is incremented by the value of @DollarRevenue, We now insert the YearMth, Month, Item Count, Dollar Revenue AND the running total into our table variable @DollarTable, and then fetch the next row.

Once all the rows are processed, @@FETCH_STATUS is no longer 0 and the looping is halted.

We then insert the contents of the table variable @DollarTable into another temporary table for further row processing.

The results of the cumulative table may be seen below:

YearMth

Month

Item Count

Dollar Revenue

Cumulative

201207

July

4

122

122

201208

August

3

12

134

201209

September

3

143

277

201210

October

6

66

343

201211

November

6

88

431

201212

December

5

77

508

201301

January

7

321

829

201302

February

7

465

1294

201303

March

6

876

2170

201304

April

15

906

3076

201305

May

8

756

3832

201306

June

4

32

3864

Summary

In this post, I have shown a manner in which a cumulative total of monthly income can be created using two temporary tables, a cursor and a table variable.

In my next posting, I shall show how we can utilize the Pivot function to process the data so that the months are column based, with the dollar revenues and cumulative revenue values, row based.

As always, should you have any questions or thoughts that may have arisen, please contact me at steve.simon@sqlpass.org