Postgresql 中的时间窗口滚动总和

Jiv*_*van 2 postgresql time-series window-functions rolling-computation

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

\n

原始数据位于前三列(日期、销售员、金额):

\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
日期推销员数量3 滚动天数总和
2020-01-01约翰1010
2020-01-02约翰1525
2020-01-03约翰833
2020-01-04约翰1235
2020-01-05约翰1131
2020-01-01丹尼尔55
2020-01-02丹尼尔611
2020-01-03丹尼尔718
2020-01-04丹尼尔821
2020-01-05丹尼尔924
\n
\n

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

\n

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

\n

Pandas\' 方式(根据记忆,确切的语法可能略有不同) \xe2\x80\x94 无法获得任何简洁的信息:

\n
df.groupby(\'salesman\').rolling(\'3d\').sum()\n
Run Code Online (Sandbox Code Playgroud)\n

S-M*_*Man 7

演示:db<>fiddle

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

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

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