【问题标题】:Average on 12 preceding months interval and ISO Weeks前 12 个月间隔和 ISO 周的平均值
【发布时间】:2021-03-25 23:52:43
【问题描述】:

我有以下查询来获取前 12 个月的平均单位,但我的问题是前 12 个月没有考虑到 ISO 一年中的第 1 周,比如这个例子:

SELECT
    *,
   avg(units) OVER (                                             
       ORDER BY to_date(year::text || '-' || week::text, 'IYYY-IW')     
       RANGE between interval '12 months' preceding and current row)
FROM
   rolling_year_table 
   order by year,week;

基本上 ISO 2020 年第 1 周(实际上是 '2019-12-30')在计算中没有考虑在内。

有没有办法说前 12 个月和当前行但使用 ISO 周?

谢谢,

【问题讨论】:

    标签: sql postgresql datetime window-functions date-arithmetic


    【解决方案1】:

    评论太长了。

    我认为没有简单的方法可以做到这一点。问题是“周”和“年”之间的差异。在 12 个月的时间里,大约有 52.2 周。所以,您要问的是,有时“12 个月”期间有 52 周,有时有 53 周。

    认为您可以根据过去 52 周进行累积计算,然后使用条件逻辑将之前的第 53 周包括在内。问题是 。 . .我不知道返回 53 周的确切规则是什么。

    如果唯一的问题是在一年的第 53 周应该包括整年,那么这将很容易包括在内。其伪代码是:

    (case when isoweek = 53
          then avg() over (. . . range between '53 week' preceding and current row)
          else avg() over (. . . range between '52 week' preceding and current row)
     end)
    

    编辑:

    我不能 100% 确定这是否适用于您的用例。但我有一个想法,可以做你想做的事。那就是将一年中的周数枚举为一年中的分数。因此,有 52 周的年份会有一个枚举,而有 53 周的年份会有另一个。

    这看起来像:

    select . . .,
           avg(units) over (order by year + (isoweek - 1) / weeks_in_year
                            range between 1 preceding and current row
                           )
    from (select t.*,
                 extract(isoyear from dte) as isoyear,
                 extract(week from dte) as isoweek,
                 greatest(extract(week from date_trunc('year', dte) + interval '1 year - 1 day'), 53) as weeks_in_year
    f      from t
         ) t;
    

    您需要对此进行测试,看看它是否能达到您真正想要的效果。正如我在这个答案开头所说的那样,“12 个月前”对于 ISO 周没有明确定义,但这可能是一个合理的解释。

    【讨论】:

    • 谢谢,我唯一遇到的问题是回溯 52 或 53 周并不会影响例如 2020 年的第 1 周,如 2019 年 12 月所示
    • @Matias 。 . .我不完全明白你的评论。回溯 52 或 53 周时不考虑等年。
    【解决方案2】:

    这不是你想要的吗?

    select ry.*,
       avg(units) over (                                             
           order by year * 100 + week
           range between 100 preceding and current row
    from rolling_year_table 
    order by year,week;
    

    假设当前行是 2020 年第 45 周,这将从 2019 年的同一周到当前行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-04
      • 1970-01-01
      • 1970-01-01
      • 2014-08-22
      相关资源
      最近更新 更多