PostgreSQL:间隔“ 10天”和当前行之间的范围

时间:2019-03-14 19:58:41

标签: sql postgresql range window-functions

我有一张桌子,上面存放着每个物品的每日价格。如果价格尚未更新,则该日期没有该商品的记录。

我需要编写一个查询,该查询针对每个项目检索具有从当前行日期起10天的回溯期的最新价格,否则返回NULL。我正在考虑使用RANGE BETWEEN INTERVAL语句来实现这一点。像这样:

SELECT
    DATE(datetime),
    item_id,
    LAST(price) OVER(
        PARTITION BY item_id
        ORDER BY datetime DESC
        RANGE BETWEEN INTERVAL '10 DAYS' AND CURRENT ROW
    ) AS most_recent_price_within_last_10days
FROM ...
GROUP BY
    date,
    item_id,
    price

不幸的是,此查询引发错误:

LINE 20:  RANGE BETWEEN INTERVAL '10 DAY' PRECEDING AND CURRENT ROW
          ^

我碰到一个旧的博客帖子,说在Postgres中无法进行此操作。这仍然准确吗?

2 个答案:

答案 0 :(得分:1)

您可以使用ROW_NUMBER()提取最近10天内每个项目的最新记录:

SELECT * 
FROM (
    SELECT
        DATE(datetime),
        item_id,
        price AS most_recent_price_within_last_10days,
        ROW_NUMBER() OVER(PARTITION BY item_id ORDER BY datetime DESC) rn
    FROM ...
    WHERE datetime > NOW() - INTERVAL '10 DAY'
) x WHERE rn = 1

在子查询中,WHERE子句对日期范围进行过滤; ROW_NUMBER()为具有相同item_id的记录组中的每个记录分配一个等级,以最近的记录为准。然后,外部查询仅过滤行号为1的记录。

答案 1 :(得分:1)

一种方法是使用LAG()和一些比较:

(CASE WHEN LAG(datetime) OVER (PARTITION BY item_id ORDER BY datetime) > datetime - interval '10 days'
      THEN LAG(price) OVER (PARTITION BY item_id ORDER BY datetime)
 END) as most_recent_price_within_last_10days

也就是说,您要寻找的价格在前一行。唯一的问题是该行上的日期是否足够新。