【问题标题】:How to express window frame in SQL window function relating to property value of current row?如何在 SQL 窗口函数中表示与当前行的属性值相关的窗口框架?
【发布时间】:2019-03-05 05:02:16
【问题描述】:

考虑以下形式的事件表:id,price,timestamp。对于每个事件,我想获取在[curEvent.timestamp, curEvent.timestamp + 10sec] 之间发生的所有事件的min(price)

似乎 SQL 窗口函数将是一个合乎逻辑的候选者。

例如,如果我确定在当前事件之后要检查多少个事件以计算 min(price),则可以这样完成:

SELECT *,min(price) OVER (ORDER BY timestamp ROWS BETWEEN 1 FOLLOWING AND 100 FOLLOWING) AS min_price from events

但是,我不知道前面的事件/行数。相反,我希望它是基于[curEvent.timestamp, curEvent.timestamp + 10sec]的变量

这可能吗?

【问题讨论】:

  • 为什么投反对票?
  • 我也不知道。

标签: sql postgresql select window-functions


【解决方案1】:

我想不出用窗口函数来做到这一点的方法,但您可以改用相关子查询:

SELECT *,
       (SELECT MIN(price)
        FROM   events
        WHERE  ts BETWEEN e.ts AND e.ts + INTERVAL '10 SECOND')
FROM   events e

【讨论】:

  • 这是行不通的,因为这个WHERE 子句与<= 比较也会查看不想要的过去。你应该把它改成WHERE ts BETWEEN e.ts AND e.ts + INTERVAL '10 SECOND'dbfiddle.uk/…
  • @S-Man 不错的收获!在那里编辑。
  • 还是不错的解决方案。
【解决方案2】:

PostgreSQL 11 解决方案

demo: db<>fiddle

SELECT
    price, 
    ts,
    min(price) OVER (ORDER BY ts RANGE BETWEEN CURRENT ROW AND INTERVAL '10 seconds' FOLLOWING)
FROM times

Postgres 11 为窗口函数添加了 RANGE BETWEEN INTERVALs 的功能,这完全符合您的期望 (documentation):

样本数据(前两列)和结果(第三列):

price   ts                      min
1       2018-09-09 10:00:00     1
2       2018-09-09 10:00:04     2
100     2018-09-09 10:00:09.8   10
200     2018-09-09 10:00:10     3.5
20      2018-09-09 10:00:11     3.5
10      2018-09-09 10:00:19     3.5
3.5     2018-09-09 10:00:20     3.5
35      2018-09-09 10:00:21     35

Further reading, JOOQ Blog

【讨论】:

  • 啊,太棒了。已经接受了另一个答案,但这看起来更好。很快就会尝试。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-25
  • 1970-01-01
  • 1970-01-01
  • 2017-08-14
  • 2018-08-20
  • 2018-06-09
  • 1970-01-01
相关资源
最近更新 更多