繁体   English   中英

sql中的动态滚动平均值

[英]dynamic rolling average in sql

希望我能正确解释这一点

我正在尝试计算滚动平均值,但前面的行数可变,具体取决于另一列的滚动总和。 或者换句话说,我想计算 b 列的最近平均值,在前几行中 a 列的总和至少为 X

示例数据:

CREATE TEMP TABLE t (ts timestamp NOT NULL, a int, b int);

INSERT INTO t VALUES
 ('20200929 11:00',1,50)
,('20200929 12:00',3,25)
,('20200929 13:00',1,20)
,('20200929 14:00',1,19)
,('20200929 15:00',2,25)
,('20200929 16:00',1,22)
,('20200929 17:00',3,19) 

期望结果,X = 3:

ts                  a   b   row_from row_to average_b
2020-09-29 11:00    1   50  NULL     NULL   NULL
2020-09-29 12:00    3   25  1        1      50
2020-09-29 13:00    1   20  2        2      25
2020-09-29 14:00    1   19  2        3      22.5
2020-09-29 15:00    2   25  2        4      21.333
2020-09-29 16:00    1   22  4        5      22.5
2020-09-29 17:00    3   19  5        6      23.5

我没有计算当前行的 a 值,所以 row_to 总是前一行。

第三行只需要第 2 行

第四行需要第 2 行和第 3 行,因为第 2 行本身不是 >=3。 我不介意超过 X 值。

我可以对可变行数求平均值,但我不知道如何计算所需的 row_from。 我想这在 python 中很容易,但是在 TSQL 中有一种基于集合的方法吗?

我使用的是 PostgreSQL 10.5,但也可以使用 SQLServer 2019

我想不出如何在没有递归的情况下做到这一点。

除了16:00条目的算术错误( (19 + 25)/2 = 22 ),这会产生您想要的输出:

with recursive nums as (
  select *, 
         row_number() over (order by ts) as rn
    from t
), stoprns as (
  select *, rn as row_to, a as runsum
    from nums
  union all
  select s.ts, s.a, s.b, n.rn, s.row_to, s.runsum + n.a
    from stoprns s
         join nums n 
           on n.rn = s.rn - 1
          and s.runsum < 3
), ranges as(
  select n.rn, n.ts, n.a, n.b, 
         min(s.rn) as row_from, 
         s.row_to
    from nums n
         left join stoprns s
                on s.row_to = n.rn - 1
   group by s.row_to, n.rn, n.ts, n.a, n.b
)
select *, 
       (select avg(b) from nums where rn between row_from and row_to) as average_b
  from ranges
 group by rn, ts, a, b, row_from, row_to
 order by rn
;

根据您的表的大小,这在性能方面可能不切实际。

工作数据库<>小提琴。

暂无
暂无

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

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