如何根据日期计算2个条目之间的差异?

问题描述

我有一个像这样的Oracle数据库视图:

DATE       | PRODUCT_NUMBER | PRODUCT_COUNT | PRODUCT_FACTOR
2018-01-01 | 1              | 10            | 3
2018-03-15 | 1              | 8             | 3
2019-02-11 | 1              | 11            | 3
2019-08-01 | 1              | 5             | 3
2019-08-01 | 2              | 20            | 5
2019-08-02 | 2              | 15            | 5
2019-06-01 | 2              | 5             | 5
2020-07-01 | 2              | 30            | 5
2018-07-07 | 3              | 100           | 2

在哪里

  • DATE是日期
  • NUMBER是唯一的产品编号
  • COUNT是存储设施中“产品编号”中的项目数
  • FACTOR是可放入存储架的产品数量

我现在需要知道自上次更新以来每个产品编号的更改量。 由于第一个条目没有可比较的过去日期,因此更改是不确定的,例如NULL,NONE,0左右。没关系,只要我以后可以将其过滤掉即可。

某些产品只有1个条目,应忽略这些条目(不计算差值)。

最终结果应为:

DATE       | PRODUCT_NUMBER | PRODUCT_COUNT | PRODUCT_FACTOR | PRODUCT_CHANGE | CHANGE_FACTOR
2018-01-01 | 1              | 10            | 3              | NULL           | NULL
2018-03-15 | 1              | 8             | 3              | 2   # 10-8     | 6  # 2*3
2019-02-11 | 1              | 11            | 3              | -3  # 8-11     | -9 # 3*-3
2019-08-01 | 1              | 5             | 3              | 6   # 11-5     | 18 # 6*3
2019-08-01 | 2              | 20            | 5              | -15 # 5-20     | -75 # -15*5
2019-08-02 | 2              | 15            | 5              | 5   # 20-15    | 25 # 5*5
2019-06-01 | 2              | 5             | 5              | NULL           | NULL
2020-07-01 | 2              | 30            | 5              | -15 # 15-30    | -75 # -15*5

如何在Oracle sql中实现这一目标?

解决方法

最终结果有点不清楚:

  • 为什么要比较product_number 2的15和5值-2019-06-01小于2019-08-01并应排在第一行
  • 为什么第一行产品1的change_factor为3而产品2为什么为空
  • 为什么将2019-02-11的change_factor计算为11 * 0而不是0 * 3

假设所有这些都是错别字(从2019-06-01更改为2019-09-01),则可以使用以下内容

select dt,product_number,product_count,product_factor,product_change,product_change*product_factor change_factor
from (
    select "DATE" dt,greatest(lag(product_count) over(partition by product_number order by "DATE") - product_count,0) product_change
    from test_tab t1
    where (select count(1) from test_tab t2 where t1.product_number = t2.product_number and rownum < 3) > 1
)

fiddle

另请参阅LAG documentation