T-SQL:计算一系列行的小​​计

时间:2010-04-07 19:47:10

标签: sql tsql sql-server-2008

MSSQL 2008.我正在尝试构造一个SQL语句,它返回列B介于2个已知范围之间的所有行的列A的总和。范围是一个滑动窗口,应该重新计算,因为它可能使用循环。

这是我正在尝试做的一个例子,从我的实际问题中简化了很多。假设我有这些数据:

表:测试

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

我想构建一个查询,在上表中每十年返回1行,如下所示:

期望的结果:

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

第一行是2000 - 2009年的全部销售额,第二行是2010 - 2019年的第二行。 DecadeEnd是一个滑动窗口,它按结果集中每行的set ammount向前移动。为了说明,这是我可以使用循环实现此目的的一种方法:

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

这会返回我想要的数据:

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

但效率很低。我该如何构建这样的查询?

3 个答案:

答案 0 :(得分:3)

这样的东西
SELECT  (Year / 10) * 10,
        SUM(Sales)
FROM    @Table
GROUP BY (Year / 10) * 10

看一下这里的例子

DECLARE @Table TABLE(
    Year INT,
    Sales FLOAT
)

INSERT INTO @Table SELECT 2000,200 
INSERT INTO @Table SELECT 2001,200 
INSERT INTO @Table SELECT 2002,200 
INSERT INTO @Table SELECT 2003,200 
INSERT INTO @Table SELECT 2004,200 
INSERT INTO @Table SELECT 2005,200 
INSERT INTO @Table SELECT 2006,200 
INSERT INTO @Table SELECT 2007,200 
INSERT INTO @Table SELECT 2008,200 
INSERT INTO @Table SELECT 2009,200 
INSERT INTO @Table SELECT 2010,200 
INSERT INTO @Table SELECT 2011,200 
INSERT INTO @Table SELECT 2012,200 
INSERT INTO @Table SELECT 2013,200 
INSERT INTO @Table SELECT 2014,200 
INSERT INTO @Table SELECT 2015,200 
INSERT INTO @Table SELECT 2016,200 
INSERT INTO @Table SELECT 2017,200 
INSERT INTO @Table SELECT 2018,200 
INSERT INTO @Table SELECT 2019,200 

SELECT  (Year / 10) * 10,
        SUM(Sales)
FROM    @Table
GROUP BY (Year / 10) * 10

输出

Decade      SumOfSales
----------- ----------------------
2000        2000
2010        2000

答案 1 :(得分:1)

怎么样:

select sum(sales) as TotalSales, max([year]) as DecadeEnd from Test
group by year / 10

只要(year / 10) * 10是整数,就不必Year

编辑: 如果年份是浮点数,则间隔为2。5年而不是10年

select sum(sales) as TotalSales, max([year]) as DecadeEnd from Test
group by convert(integer, (year * 10)) / 25

答案 2 :(得分:0)

对于复杂的操作,您应该使用SQL Server中注册的程序集中的.NET方法。 从SQL 2005开始,您可以注册.NET程序集并从SQL服务器调用其方法。

Managed code in SQL