2017-02-16 11 views
2

В настоящее время у меня есть запрос, который производит данные за каждый квартал, я бы хотел, чтобы общая сумма была общей. Таким образом, показатели квартала 2 будут добавлены к кварталу 1 и т. Д. До конца финансового года, когда процесс начнется снова.Совокупный итог для кварталов

select datepart(year,date) as Year, 
    CASE 
    WHEN MONTH(date) BETWEEN 1 AND 3 THEN convert(char(4), YEAR(date) - 1) + 'Q4' 
    WHEN MONTH(date) BETWEEN 4 AND 6 THEN convert(char(4), YEAR(date) - 0) + 'Q1' 
    WHEN MONTH(date) BETWEEN 7 AND 9 THEN convert(char(4), YEAR(date) - 0) + 'Q2' 
    WHEN MONTH(date) BETWEEN 10 AND 12 THEN convert(char(4), YEAR(date) - 0) + 'Q3' 
END AS Quarter, 

Data1, 
Data2, 

FROM TABLE 

GROUP BY datepart(year,date), 
    CASE 
    WHEN MONTH(date) BETWEEN 1 AND 3 THEN convert(char(4), YEAR(date) - 1) + 'Q4' 
    WHEN MONTH(date) BETWEEN 4 AND 6 THEN convert(char(4), YEAR(date) - 0) + 'Q1' 
    WHEN MONTH(date) BETWEEN 7 AND 9 THEN convert(char(4), YEAR(date) - 0) + 'Q2' 
    WHEN MONTH(date) BETWEEN 10 AND 12 THEN convert(char(4), YEAR(date) - 0) + 'Q3' 
END 

Это то, что я в настоящее время получить

year quarter  data1  data2 

2016  Q1   10   4 
2016  Q2   5    6 
2016  Q3   4    2 
2017  Q4   1    1 

Я хотел бы выход выглядеть следующим образом

year quarter  data1  data2 

2016  Q1   10   4 
2016  Q2   15   10 
2016  Q3   19   12 
2017  Q4   20   13 

Спасибо за любую помощь

ответ

0

Вы можете обернуть запрос в CTE и использовать CROSS APPLY для расчета суммарной суммы:

;WITH CTE AS (
    -- your query 
) 
SELECT t1.year, t1.quarter, t1.data1, t3.cumulative_sum 
FROM CTE AS t1 
CROSS APPLY (
    SELECT SUM(data2) AS cumulative_sum 
    FROM CTE AS t2 
    WHERE t2.year <= t1.year AND t2.quarter <= t1.quarter) AS t3 
0

Во-первых, ваш запрос может быть упрощена:

SELECT datepart(year, date) as Year, 
     datename(year, date) + 'Q' + datename(quarter, dateadd(month, -3, date)) as quarter, 
     SUM(Data1) as Data1, SUM(Data2) as Data2 
FROM TABLE 
GROUP BY datepart(year, date) as Year, 
     datename(year, date) + 'Q' + datename(quarter, dateadd(month, -3, date)) as quarter 
ORDER BY quarter; 

Обратите внимание на использование datename(). Это возвращает строку, а не число, что проще для конкатенации строк. Кроме того, это упрощает логику, просто вычитая 3 месяца, чтобы получить квартал.

В SQL Server 2012+ вы можете использовать встроенную функциональность для совокупной суммы. В SQL Server 2008 один метод использует apply:

WITH t as (
     SELECT datepart(year, date) as Year, 
      datename(year, date) + 'Q' + datename(quarter, dateadd(month, -3, date)) as quarter, 
      SUM(Data1) as Data1, SUM(Data2) as Data2 
     FROM TABLE 
     GROUP BY datepart(year, date) as Year, 
       datename(year, date) + 'Q' + datename(quarter, dateadd(month, -3, date)) as quarter 
    ) 
SELECT t.*, tt.data2 
FROM t OUTER APPLY 
    (SELECT SUM(data1) as data2 
     FROM t t2 
     WHERE t2.quarter <= t.quarter 
    ) tt; 
+0

Я думаю, вы пропустите агрегацию для Data1, Data2? И не уверен, почему вы не использовали функцию окна вместо –

+0

@JuanCarlosOropeza. , , Потому что ты спросил. В запросе было исправлено несколько вопросов (расчет квартала и «применить»). Я просто не был сосредоточен на фактической агрегации данных. –