T-SQL calculate moving average

后端 未结 2 1309
长发绾君心
长发绾君心 2020-12-01 16:23

I am working with SQL Server 2008 R2, trying to calculate a moving average. For each record in my view, I would like to collect the values of the 250 previous records, and t

2条回答
  •  醉话见心
    2020-12-01 16:45

    The window functions in SQL 2008 are rather limited compared to later versions and if I remember correct you can only partition and you can't use any rows/range frame limit but I think this might be what you want:

    ;WITH cte (rn, transactionid, value) AS (
        SELECT 
           rn = ROW_NUMBER() OVER (ORDER BY transactionid),
           transactionid,
           value
        FROM your_table
    )
    
    SELECT 
        transactionid, 
        value, 
        movagv = (
            SELECT AVG(value) 
            FROM cte AS inner_ref
            -- average is calculated for 250 previous to current row inclusive
            -- I might have set the limit one row to large, maybe it should be 249
            WHERE inner_ref.rn BETWEEN outer_ref.rn-250 AND outer_ref.rn
            ) 
    FROM cte AS outer_ref
    

    Note that it applies a correlated sub-query to every row and performance might not be great.

    With the later versions you could have used window frame functions and done something like this:

    SELECT 
        transactionid, 
        value,
        -- avg over the 250 rows counting from the previous row
        AVG(value) OVER (ORDER BY transactionid  
                         ROWS BETWEEN 251 PRECEDING AND 1 PRECEDING),
        -- or 250 rows counting from current
        AVG(value) OVER (ORDER BY transactionid  
                         ROWS BETWEEN 250 PRECEDING AND CURRENT ROW)
    FROM your_table
    

提交回复
热议问题