基于列中的 n 值的滚动平均值

问题描述 投票:0回答:1

我有一个具有以下结构的表格 -

| date1       | grp    | value | n |
|:-----------:|:------:|:-----:|:-:|
| 2023-10-01  | g1     | 10    | 30|
| 2023-10-02  | g1     | 15    | 30|
| 2023-10-03  | g1     | 12    | 30|
| 2023-10-01  | g2     | 18    | 10|
| 2023-10-02  | g3     | 12    | 10|
| 2023-10-03  | g4     | 19    | 10|

我想计算过去 n 天的值列的滚动平均值,其中 n = 第 n 列的值 这意味着对于 g1,我想计算最近 30 天的滚动平均值,而对于 g2,我想计算最近 10 天的滚动平均值。

无法通过我的 presto sql 查询 -

SELECT 
    date1, 
    grp, 
    n, 
    AVG(value) OVER (PARTITION BY grp ORDER BY date1 ROWS BETWEEN CAST(n AS INT) PRECEDING AND CURRENT ROW) AS PRIMARY
FROM tbl
GROUP BY 1, 2, 3;

上面的查询出现错误 GROUP BY 子句不能包含聚合、窗口函数或分组操作

此类用例有解决方案吗?

sql presto rolling-computation
1个回答
0
投票

我不使用 Presto,因此以下内容是在 Postgres 中,但我相信它应该适用。

您的问题中所述的错误可以通过在尝试对该列进行分组之前运行窗口函数来解决。即在子查询(或 CTE)中运行窗口函数,然后您可以在后续分组中引用该列。不过,您也可以使用 MAX() 来代替(如下所示)。另一种方法是简单地使用 select different 而不是分组 - 但分组确实提供了更多可能性。

另请注意,您不太可能在窗口函数内使用变量来更改考虑的行数,但您可以使用 case 表达式来模拟此操作,例如:

SELECT
      date1
    , grp
    , max(av_value)
FROM (
    SELECT
          date1
        , grp
        , n
        , case
            when n = 30 then
               avg(value) over(partition by grp order by date1 
                               rows between 30 preceding and current row)
            when n = 20 then
               avg(value) over(partition by grp order by date1 
                               rows between 20 preceding and current row)
            when n = 10 then
               avg(value) over(partition by grp order by date1 
                               rows between 10 preceding and current row)
          end as av_value
    FROM tbl
    ) d
GROUP BY
      date1
    , grp
日期1 grp 最大
2023-10-03 g1 12.3333333333333333
2023-10-01 g1 10.0000000000000000
2023-10-02 g3 12.0000000000000000
2023-10-03 g4 19.0000000000000000
2023-10-02 g1 12.5000000000000000
2023-10-01 g2 18.0000000000000000

小提琴

© www.soinside.com 2019 - 2024. All rights reserved.