PostgreSQL:在有时间条件的情况下插入新记录时更新旧记录

时间:2019-04-23 15:53:51

标签: python sql postgresql etl

因此,我有一个postgresql表,该表会不断添加具有不同项目的新记录

item      period                     cost    cost_diff
---------------------------------------------------------
 bag    2019-03-15T18:15:00.000Z     100         0
 shoe   2019-03-15T18:15:00.000Z     200         0

因此,当记录进入时,它们的cost_diff将为0。但是当新记录变为这样时

item      period                     cost    cost_diff
---------------------------------------------------------
 bag    2019-03-15T18:15:00.000Z     100         0
 shoe   2019-03-15T18:15:00.000Z     200         0
 bag    2019-03-15T18:30:00.000Z     150         0
 shoe   2019-03-15T18:45:00.000Z     300         0

将通过使用(新成本-旧成本)来更新旧记录的cost_diff,但仅当该时间段是在0、15时插入数据的下一个15分钟时,才会更新该记录,30和45分钟。

item      period                     cost    cost_diff
---------------------------------------------------------
 bag    2019-03-15T18:15:00.000Z     100        50 (150-100)
 shoe   2019-03-15T18:15:00.000Z     200         0 (no update)
 bag    2019-03-15T18:30:00.000Z     150         0
 shoe   2019-03-15T18:45:00.000Z     300         0

上表显示,插入了具有15分钟范围(18:15-> 18:30)的袋的较新记录,因此,周期为18:15的袋行会将cost_diff列的价格从18:30减去18:15的成本,这将是150-50 =100。虽然旧鞋行将不会更新(仍为0),因为进入的新鞋记录不是接下来的15分钟(18:15) -> 18:45),当表中插入时间为18:30的鞋行等用于其他记录(有很多项,不仅是如图所示的包和袋子)时,它将进行更新。

因此,我将如何基于此问题创建查询,因为记录将不断进入该表中,可以仅使用sql查询来完成此操作,还是需要使用python来帮助解决此问题(我正在做一个etl管道,该任务包括在转换过程中)

谢谢

1 个答案:

答案 0 :(得分:0)

您可以通过查询执行此操作。使用lead()

select t.*,
       (case when lead(period) over (partition by item order by period) < period + interval '15 minute'
             then lead(cost) over (partition by item order by period) - cost
             else 0
       ) as cost_diff
from t;