T-SQL: Compute Subtotals For A Range Of Rows

Posted by John Dibling on Stack Overflow See other posts from Stack Overflow or by John Dibling
Published on 2010-04-07T19:47:10Z Indexed on 2010/04/07 20:03 UTC
Read the original article Hit count: 1356

Filed under:
|
|

MSSQL 2008. I am trying to construct a SQL statement which returns the total of column B for all rows where column A is between 2 known ranges. The range is a sliding window, and should be recomputed as it might be using a loop.

Here is an example of what I'm trying to do, much simplified from my actual problem. Suppose I have this data:

table: Test

Year        Sales
----------- -----------
2000        200
2001        200
2002        200
2003        200
2004        200
2005        200
2006        200
2007        200
2008        200
2009        200
2010        200
2011        200
2012        200
2013        200
2014        200
2015        200
2016        200
2017        200
2018        200
2019        200

I want to construct a query which returns 1 row for every decade in the above table, like this:

Desired Results:

DecadeEnd  TotalSales 
---------  ----------
2009        2000
2010        2000    

Where the first row is all the sales for the years 2000-2009, the second for years 2010-2019. The DecadeEnd is a sliding window that moves forward by a set ammount for each row in the result set. To illustrate, here is one way I can accomplish this using a loop:

declare @startYear int
set @startYear = (select top(1) [Year] from Test order by [Year] asc)
declare @endYear int
set @endYear = (select top(1) [Year] from Test order by [Year] desc)

select @startYear, @endYear

create table DecadeSummary (DecadeEnd int, TtlSales int)
declare @i int
-- first decade ends 9 years after the first data point
set @i = (@startYear + 9)   
while @i <= @endYear
begin
    declare @ttlSalesThisDecade int
    set @ttlSalesThisDecade = (select SUM(Sales) from Test where(Year <= @i and Year >= (@i-9)))
    insert into DecadeSummary values(@i, @ttlSalesThisDecade)

    set @i = (@i + 9)
end

select * from DecadeSummary

This returns the data I want:

DecadeEnd   TtlSales
----------- -----------
2009        2000
2018        2000

But it is very inefficient. How can I construct such a query?

© Stack Overflow or respective owner

Related posts about sql

Related posts about tsql