简体   繁体   English

使用 OVER RANGE BETWEEN days 移动平均值

[英]Moving avg using OVER RANGE BETWEEN days

I want to find the average of item price bought within the last 365 days.我想查找过去 365 天内购买的商品的平均价格。 Items are not guaranteed to be bought every day, so I can't fix the number of rows to look back at.物品不保证每天都能买到,所以无法固定回头看的行数。 So I am trying to use RANGE instead of ROWS, specifying that I look back 365 days from current row's date.所以我尝试使用 RANGE 而不是 ROWS,指定我从当前行的日期开始回顾 365 天。

Sample data:样本数据:

  • Group by Store and Item按商店和项目分组
  • I want to find the avg of prices bought within the last 12 months我想找到过去 12 个月内购买的平均价格
Store店铺 Item物品 Date bought购买日期 Price价格 Avg price across last 365 days过去 365 天的平均价格
Store 1商店 1 Item 1第 1 项 1/2/2022 2022 年 1 月 2 日 1.00 1.00 1.00 1.00
Store 1商店 1 Item 1第 1 项 6/1/2022 6/1/2022 1.75 1.75 1.375 1.375
Store 1商店 1 Item 1第 1 项 11/2/2022 11/2/2022 2.10 2.10 1.617 1.617
Store 1商店 1 Item 1第 1 项 1/5/2023 2023 年 1 月 5 日 3.00 3.00 2.283 2.283
Store 2店铺 2 Item 1第 1 项 3/2/2022 2022 年 3 月 2 日 1.55 1.55 1.55 1.55
Store 2店铺 2 Item 1第 1 项 5/5/2022 2022 年 5 月 5 日 2.80 2.80 2.175 2.175

I have tried:我努力了:

SELECT  
    store, item, date, price,
    SUM(price) OVER (PARTITION BY store, item
                     ORDER BY date ASC
                     RANGE BETWEEN 365 DAY PRECEDING AND CURRENT ROW) AS avg_price
FROM table

Error I get is:我得到的错误是:

Msg 102, Level 15, State 1, Line 102消息 102,15 级,State 1,第 102 行
Incorrect syntax near 'DAY' “DAY”附近的语法不正确

I have tried these variations to address the error but can't get past it:我已经尝试了这些变体来解决错误但无法克服它:

  1. RANGE BETWEEN '365' DAY PRECEDING AND CURRENT ROW
  2. RANGE BETWEEN INTERVAL 365 DAY PRECEDING AND CURRENT ROW
  3. RANGE BETWEEN 365 PRECEDING AND CURRENT ROW

#3 produces the error #3 产生错误

Msg 4194, Level 16, State 1, Line 98 Msg 4194, Level 16, State 1, Line 98
RANGE is only supported with UNBOUNDED and CURRENT ROW window frame delimiters. RANGE 仅支持 UNBOUNDED 和 CURRENT ROW window 帧分隔符。

Is this a syntax error?这是语法错误吗? I am using Microsoft SQL Server Management Studio.我正在使用 Microsoft SQL Server Management Studio。

SELECT  
    store, 
    item, 
    date, 
    price,
    AVG(price) AS avg_price
FROM table
WHERE
    date > (select dateadd(year, -1, getdate()));
GROUP BY
    store,
    item,
    date,
    price

the WHERE query will reduce your data to all the input in the last year. WHERE查询会将您的数据减少到去年的所有输入。 SQL already comes with an averageing functions called AVG . SQL 已经带有一个称为AVG的平均函数。 Remove the GROUP BY if you don't want all of your data to be in groups.如果您不希望所有数据都在组中,请删除GROUP BY

A good old self-join should work (I converted your dates into ISO format):一个很好的旧自连接应该可以工作(我将您的日期转换为 ISO 格式):

with cte as (
    select *
    
    from (
        VALUES  (N'Store 1', N'Item 1', N'2022-01-02', 1.00, 1.00)
        ,   (N'Store 1', N'Item 1', N'2022-06-01', 1.75, 1.375)
        ,   (N'Store 1', N'Item 1', N'2022-11-01', 2.10, 1.617)
        ,   (N'Store 1', N'Item 1', N'2023-01-05', 3.00, 2.283)
        ,   (N'Store 2', N'Item 1', N'2022-03-02', 1.55, 1.55)
        ,   (N'Store 2', N'Item 1', N'2022-05-05', 2.80, 2.175)
    ) t (Store,Item,[Date bought],Price,[Avg price across last 365 days])
    )
select  AVG(c2.price), c.Store, c.Item, c.[Date bought]
from CTE c
LEFT JOIN CTE c2
    On  c2.Store = c.Store
    AND c2.Item = c.Item
    AND c2.[Date bought]  between DATEADD(YEAR, -1,CAST(c.[Date bought] AS DATETIME)) AND c.[Date bought]
GROUP BY c.Store, c.Item, c.[Date bought]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM