T-SQL: вычислить промежуточные итоги для ряда строк - PullRequest
0 голосов
/ 07 апреля 2010

MSSQL 2008. Я пытаюсь создать оператор SQL, который возвращает сумму столбца B для всех строк, где столбец A находится между 2 известными диапазонами. Диапазон представляет собой скользящее окно, и его следует пересчитать, так как он может использовать цикл.

Вот пример того, что я пытаюсь сделать, очень упрощенный из моей реальной проблемы. Предположим, у меня есть эти данные:

Таблица: Тест

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 - это скользящее окно, которое перемещается вперед на установленное количество для каждой строки в наборе результатов. Чтобы проиллюстрировать это, я могу сделать это одним из способов, используя цикл:

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 ]

3 голосов
/ 07 апреля 2010

Как насчет чего-то вроде

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 голос
/ 08 апреля 2010

Как насчет:

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
0 голосов
/ 07 апреля 2010

ИМХО для сложных операций вы должны использовать метод .NET из сборки, зарегистрированной на SQL-сервере.Начиная с SQL 2005, вы можете зарегистрировать сборку .NET и вызвать ее метод с сервера SQL.

Управляемый код в SQL

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...