【问题标题】:Rolling 7 day average using calculated averages使用计算的平均值滚动 7 天平均值
【发布时间】:2021-06-04 11:01:08
【问题描述】:

可以在小提琴中使用的快速设置。

create table tbl
(avgdate date, avgvalue numeric(10,2));

insert into tbl values ('2021-01-01',10.4);
insert into tbl values ('2021-01-02',13.1);
insert into tbl values ('2021-01-03',11.35);
insert into tbl values ('2021-01-04',3.4);
insert into tbl values ('2021-01-05',7.12);
insert into tbl values ('2021-01-06',16.76);
insert into tbl values ('2021-01-07',17.2);
insert into tbl values ('2021-01-08',13.76);
insert into tbl values ('2021-01-09',10.56);
insert into tbl values ('2021-01-10',null);
insert into tbl values ('2021-01-11',null);
insert into tbl values ('2021-01-12',null);

我想写一些类似的东西

select avgdate,
   case when avgvalue is not null then avgvalue
   else
   --avg of past 7 days
end
from tbl

通常我会使用 lag 函数或 rownumber 来挑选前一行的值并对它们进行平均,这适用于第 10 行,但是当我的逻辑需要包含计算的行时会遇到错误。 1 月 12 日应该是 5 日到 9 日的平均值,加上 10 日和 11 日的计算值。

【问题讨论】:

  • 您谈论的是avgvalue 的“计算值”,但是您没有告诉我们该计算是什么。您在这里预期的结果是什么?如果你想要最后 7 行的平均值,窗口化的AVG 有什么问题?
  • 您是否已经尝试过移动平均 avg(avgvalue) OVER(ORDER BY avgdate ROWS BETWEEN 7 PRECEDING AND CURRENT ROW ) ?
  • @Larnu - 计算值是平均值。 1 月 11 日是 1 月 4 日至 10 日的平均值。 1 月 10 日是 1 月 9 日至 3 日的平均值。所以 1 月 11 日实际上是(1 月 4 日至 9 日 + 1 月 3 日至 9 日的平均值)的平均值。 Jan 12th 将进一步嵌套这个,即 avg(Jan 5th to 9th + avg (jan 3rd - 9th) + avg (jan 4th to 9th + avg of jan 3rd to 9th)...等等。

标签: sql sql-server tsql sql-server-2012


【解决方案1】:

这几乎就是你想要的代码:

coalesce(avgvalue,
         avg(avgvalue) over (order by date rows between 7 preceding and 1 preceding)
        )

等等。这选择了前 7 个值,其中一些可能是 NULL。为此,您可以使用apply

select t.*,
       coalesce(t.avgvalue, t2.avgvalue7)
from tbl t outer apply
     (select avg(t2.avgvalue) as avgvalue7
      from (select top (7) t2.avgvalue
            from tbl t2
            where t2.avgvalue is not null and
                  t2.date < t.date
            order by t2.date desc
           ) t2
     ) t2;

【讨论】:

  • close...这将使 1 月 10 日的 11.45 恢复正常,但也为 1 月 11 日和 12 日带来相同的值。 1 月 11 日应该是 avg(jan 4th to 9th + 11.45),其中 11.45 是为 1 月 10 日计算的值。 1 月 12 日应该是平均值(1 月 5 日至 11 日),其中 1 月 10 日是 3 日至 9 日的平均值),1 月 11 日是 1 月 4 日至 10 日的平均值。
  • 我应该能够从 1 月 1 日至 7 日输入的值计算 1 月 30 日,从这 7 行计算 1 月 7 日之后的每一天。我可以用游标和一些涉及循环的更hacky方法来做到这一点。寻找非循环或光标答案。
  • @Twelfth 。 . .您是说要累积平均值吗?
  • 我仍在努力寻找这个问题的答案,还没有找到任何可以以基于集合的方式累积平均值的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-07
  • 1970-01-01
  • 1970-01-01
  • 2020-04-25
  • 1970-01-01
  • 1970-01-01
  • 2013-01-14
相关资源
最近更新 更多