Sql-Server

基於某個類別的前 n 個列的總和

  • March 1, 2020

我有以下輸入,我需要計算每個類別前 x 週的值的總和。

輸入

如果 x 為 3,則輸出將如下所示:

在此處輸入圖像描述

請注意,最後一個值為 49,因為它僅將最近兩週的值添加到 x=3 以來的目前週。

我希望將 SQL 編寫為儲存過程,並且需要一些有關適當方法的幫助。

在@sp_BlitzErik 的幫助下,我嘗試使用LAG,但無法完全到達我需要的地方。這是我的查詢:

SELECT category
   ,year
   ,week
   ,value
   ,(
       LAG(value, 1, 0) OVER (
           ORDER BY category
               ,year
               ,week
           ) + LAG(value, 2, 0) OVER (
           ORDER BY category
               ,year
               ,week
           ) + value
       ) AS cumulative_value
FROM valuedata

並且輸出還不完全正確:

在此處輸入圖像描述

在 SQL Server 2014 和 2016 1上,您可以使用WINDOW函式(即OVER子句)來執行您想要的操作:

SELECT
    category, year, week, value, 
    sum(value) OVER (PARTITION BY category 
                         ORDER BY year, week 
                             ROWS 2 PRECEDING) AS retention_value_3_weeks
FROM
    t 
ORDER BY
   category, year, week ;

這是你會得到的結果:

類別 | 年份 | 週 | 價值 | 保留值_3_週
:------- | ---: | ---: | ----: | ----------------------:
一個 | 2016 | 1 | 5 | 5
一個 | 2016 | 2 | 7 | 12
一個 | 2016 | 3 | 8 | 20
乙 | 2016 | 3 | 6 | 6
乙 | 2016 | 4 | 15 | 21
乙 | 2016 | 5 | 25 | 46
c | 2016 | 3 | 25 | 25
c | 2016 | 4 | 2 | 27
c | 2016 | 5 | 21 | 48
c | 2016 | 6 | 26 | 49

請注意,x = 3您的範例被翻譯為(目前行和*2 preceding那些*)。

如果由於某種原因您不能使用該OVER子句,您仍然可以使用一些(相當複雜的)子查詢來計算相同的結果:

SELECT
   category, year, week, value,
   (SELECT 
       sum(value)
    FROM
       (SELECT TOP 3                    /* total number of rows to consider */
            value
       FROM 
          t t2
       WHERE
              t2.category = t.category  /* partition by category */
          AND t2.week <= t.week         /* current and preceding rows */
       ORDER BY
          year DESC, week DESC          /* order by criteria */
       ) AS q
    ) AS retention_value_3_weeks
FROM
   t 
ORDER BY
   category, year, week ;

在此處**的dbfiddle檢查所有內容

如果你想使用@x而不是3,你可以這樣做:

DECLARE @x AS INTEGER = 3;

SELECT
   category, year, week, value,
   (SELECT 
       sum(value)
    FROM
       (SELECT TOP (@x)                  /* total number of rows to consider */
            value
       FROM 
          t t2
       WHERE
              t2.category = t.category  /* partition by category */
          AND t2.week <= t.week         /* current and preceding rows */
       ORDER BY
          year DESC, week DESC          /* order by criteria */
       ) AS q
    ) AS retention_value_3_weeks
FROM
   t 
ORDER BY
   category, year, week ;;

dbfiddle在這裡


1)無法使用 SQL Server 2012 進行測試,因為我沒有。MS SQL Server 的文件表明它應該從 2008 版開始可用。

引用自:https://dba.stackexchange.com/questions/181773