向行添加偏移量以获得单调递增的值

时间:2018-05-01 18:49:58

标签: sql oracle

基于这个帖子(Check rows for monotonically increasing values),我有一个额外的要求: value-column表示计数器。 在我的应用中,由于某些恼人的原因,计数器值不时地重置,即从零开始。对于数据评估,我需要所有计数的累计值。我的想法是创建一个包含累计值的附加列。 只要不进行重置,新列的值就与原始值列的值相同。复位后,新列的值是最新累计值+当前计数器值。数据中可能会发生多次重置。再次,具有相同"名称"的行属于同一测量,必须按meas_date排序。

这是原始数据:

id   name   meas_date   value
1    name1  2018/01/01  1
2    name1  2018/01/02  2
3    name2  2018/01/04  2
4    name1  2018/01/03  1
5    name1  2018/01/04  5
6    name2  2018/01/05  4
7    name2  2018/01/06  2
8    name1  2018/01/05  2

期望的结果将是

id   name   meas_date   value  accumulated_value
1    name1  2018/01/01  1      1
2    name1  2018/01/02  2      2
3    name2  2018/01/04  2      2
4    name1  2018/01/03  1      3 
5    name1  2018/01/04  5      7
6    name2  2018/01/05  4      4
7    name2  2018/01/06  2      6
8    name1  2018/01/05  2      9

上面提到的线程中的LAG函数非常有助于找到重置计数器值的行。但是现在,我正在努力将其与值的积累结合起来以获得整体计数器值。

非常感谢,

基督教

2 个答案:

答案 0 :(得分:1)

我想我找到了一个解决方案,需要两个步骤:

-- 1. set flag column = 2 for all rows with values right before an reset
update TEST dst set dst.flag = (
  with src as (
    SELECT id, name, value,
    CASE WHEN value < value_next THEN 0 ELSE 2 END AS flag
    FROM (
      SELECT id, name, value,
      LEAD(value, 1, 0) OVER (PARTITION BY name order by meas_date) AS value_next
      FROM TEST
    )      
  )
  select src.flag from src where dst.id = src.id
) 

-- 2. Use SQL for Modeling to calculate the accumulated values
SELECT  name, meas_date, value, offset, value+offset as accumulated_value
FROM TEST 
MODEL RETURN UPDATED ROWS
 PARTITION BY (name) 
 DIMENSION BY (meas_date, flag)
 MEASURES (value, 0 as offset)
 RULES (
  offset[meas_date, ANY] ORDER BY meas_date = NVL(sum(NVL(value,0))[meas_date < CV(meas_date), flag=2],0) 
 ); 

在第1步之后:

id  name    meas_date   value flag
1   name1   01.01.18    1     0
2   name1   02.01.18    2     2
3   name2   04.01.18    2     0
4   name1   03.01.18    1     0
5   name1   04.01.18    5     2
6   name2   05.01.18    4     2
7   name2   06.01.18    2     2
8   name1   05.01.18    2     2

第2步的输出

name    meas_date   value  offset  accumulated_value
name1   01.01.18    1      0       1
name1   02.01.18    2      0       2
name1   03.01.18    1      2       3
name1   04.01.18    5      2       7
name1   05.01.18    2      7       9
name2   04.01.18    2      0       2
name2   05.01.18    4      0       4
name2   06.01.18    2      4       6

答案 1 :(得分:0)

这有用吗?

{{1}}