Dynamic row range when calculating moving sum/average using window functions (SQL Server)

后端 未结 3 1939
礼貌的吻别
礼貌的吻别 2021-01-18 21:10

I\'m currently working on a sample script which allows me to calculate the sum of the previous two rows and the current row. However, I would like to make the number \'2\' a

相关标签:
3条回答
  • 2021-01-18 21:16

    You can try something like this which does not use dynamic SQL.

    DECLARE @myTable TABLE  (myValue INT)
    
    INSERT INTO @myTable ( myValue ) VALUES  ( 5)
    INSERT INTO @myTable ( myValue ) VALUES  ( 6)
    INSERT INTO @myTable ( myValue ) VALUES  ( 7)
    INSERT INTO @myTable ( myValue ) VALUES  ( 8)
    INSERT INTO @myTable ( myValue ) VALUES  ( 9)
    INSERT INTO @myTable ( myValue ) VALUES  ( 10)
    
    
    DECLARE @prev_records INT = 2
    
    ;WITH CTE as 
    (
    SELECT ROW_NUMBER() OVER(ORDER BY myValue) rn,myValue FROM @myTable
    )
    SELECT (SELECT  SUM(myValue) FROM CTE t2 WHERE t2.rn BETWEEN (t1.rn  - @prev_records) AND t1.rn )
    FROM CTE t1
    

    SUM(myValue) OVER() is best option however it does not allow you to pass previous N rows using a variable.

    0 讨论(0)
  • 2021-01-18 21:25

    If possible dispersion of the range variable is not very high, you can use simple CASE statement to switch between calculations

    DECLARE @myTable TABLE  (myValue INT)
    
    -- let's say it could be between 1 and 10
    DECLARE @range int = 3;
    
    INSERT INTO @myTable ( myValue ) VALUES  ( 5)
    INSERT INTO @myTable ( myValue ) VALUES  ( 6)
    INSERT INTO @myTable ( myValue ) VALUES  ( 7)
    INSERT INTO @myTable ( myValue ) VALUES  ( 8)
    INSERT INTO @myTable ( myValue ) VALUES  ( 9)
    INSERT INTO @myTable ( myValue ) VALUES  ( 10)
    
    SELECT 
        CASE @range
            WHEN 1 THEN SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN 1 PRECEDING AND CURRENT ROW)
            WHEN 2 THEN SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)
            WHEN 3 THEN SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN 3 PRECEDING AND CURRENT ROW)
            WHEN 4 THEN SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN 4 PRECEDING AND CURRENT ROW)
            WHEN 5 THEN SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN 5 PRECEDING AND CURRENT ROW)
            WHEN 6 THEN SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN 6 PRECEDING AND CURRENT ROW)
            WHEN 7 THEN SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN 7 PRECEDING AND CURRENT ROW)
            WHEN 8 THEN SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN 8 PRECEDING AND CURRENT ROW)
            WHEN 9 THEN SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN 9 PRECEDING AND CURRENT ROW)
            WHEN 10 THEN SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN 10 PRECEDING AND CURRENT ROW)
        END
    FROM @myTable
    
    0 讨论(0)
  • DECLARE @test VARCHAR = 1
    DECLARE @sqlCommand VARCHAR(1000)
    DECLARE @myTable TABLE  (myValue INT)
    
    INSERT INTO @myTable ( myValue ) VALUES  ( 5)
    INSERT INTO @myTable ( myValue ) VALUES  ( 6)
    INSERT INTO @myTable ( myValue ) VALUES  ( 7)
    INSERT INTO @myTable ( myValue ) VALUES  ( 8)
    INSERT INTO @myTable ( myValue ) VALUES  ( 9)
    INSERT INTO @myTable ( myValue ) VALUES  ( 10)
    
    SET @sqlCommand = 'SELECT SUM(myValue) OVER (ORDER BY myValue ROWS BETWEEN ' + @test + ' PRECEDING AND CURRENT ROW)
                      FROM #temp'
    
    EXEC (@sqlCommand)
    
    0 讨论(0)
提交回复
热议问题