【问题标题】:Time-window rolling sum in PostgresqlPostgresql中的时间窗口滚动总和
【发布时间】:2021-05-12 23:25:24
【问题描述】:

我想知道是否可以在 Postgresql 中使用基于时间的窗口查询。

原始数据在前三列(日期、业务员、金额):

date salesman amount sum-3-rolling-days
2020-01-01 john 10 10
2020-01-02 john 15 25
2020-01-03 john 8 33
2020-01-04 john 12 35
2020-01-05 john 11 31
2020-01-01 daniel 5 5
2020-01-02 daniel 6 11
2020-01-03 daniel 7 18
2020-01-04 daniel 8 21
2020-01-05 daniel 9 24

第四列表示该业务员在过去三个滚动日内的总金额。

Pandas 具有执行此操作的内置函数,但我想不出在 Postgresql 中使用内置 sum() over () 语法的任何方法。我能够做到的唯一方法是使用横向连接和子查询的复杂组合,以及时间增量比较条件,这至少可以说是不雅的。

Pandas 的方式(根据记忆,确切的语法可能略有不同)——无法获得任何简洁:

df.groupby('salesman').rolling('3d').sum()

【问题讨论】:

    标签: postgresql time-series window-functions rolling-computation


    【解决方案1】:

    demos:db<>fiddle

    SELECT
        *,
        SUM(amount) OVER (
            PARTITION BY salesman                     -- 1
            ORDER BY "date"                           -- 2
            ROWS BETWEEN 2 PRECEDING AND CURRENT ROW  -- 3
        )
    FROM mytable
    
    1. 通过salesman 构建组/分区。因此,以下只会在这些分区内完成
    2. 按date 列排序
    3. 仅对当前日期和当前日期前 2 个日期之间的记录求和。这是滚动部分

    如果您使用 Postgres 11 或更高版本,您可以使用带有日期间隔的RANGE 来更精确地定义窗口,而不是计算ROWS:

    SELECT
        *,
        SUM(amount) OVER (
            PARTITION BY salesman                    
            ORDER BY "date"                          
            RANGE BETWEEN interval '2 days' PRECEDING AND CURRENT ROW
        )
    FROM mytable
    

    【讨论】:

      【解决方案2】:

      您可以使用CTE(通用表表达式)。 试试

      with data as (
      select
        date,
        salesman,
        amount
      from
        foo
      group by
        date,
        salesman
      order by
        date,
        salesman,
      )
      
      select
        *,
        sum(amount) over (
          partition by salesman order by date,
          salesman rows between unbounded preceding and current row
        ) as rolling
      from data;
      

      【讨论】:

        猜你喜欢
        • 2018-03-24
        • 1970-01-01
        • 1970-01-01
        • 2020-05-14
        • 1970-01-01
        • 1970-01-01
        • 2020-10-09
        • 2018-08-16
        • 1970-01-01
        相关资源
        最近更新 更多