Как найти последнее ненулевое значение столбца и рекурсивно найти сумму значений другого столбца - PullRequest
0 голосов
/ 14 июня 2019

Предположим, у меня есть столбец A, и в данный момент значение A равно нулю.Мне нужно вернуться к предыдущим строкам и найти ненулевое значение столбца A. Затем мне нужно найти сумму другого столбца B от точки, значение которой не видно, до текущей точки.После этого мне нужно добавить сумму B с A, которая будет новым значением A.

Для поиска ненулевого значения столбца A я написал запрос как

nvl(last_value(nullif(A,0)) ignore nulls over (order by A),0)

Но мне нужно сделать расчет B, как упомянуто выше.

nvl(last_value(nullif(A,0)) ignore nulls over (order by A),0)

Может ли кто-нибудь, пожалуйста, помогите мне?

Пример данных

A        B      date

null     20     14/06/2019

null     40     13/06/2019

10       50     12/06/2019

здесь значение A14/06/2019 следует заменить на сумму B + значение A от 12/06/2019 (которое является первым ненулевым значением A) = 20 + 40 + 50 + 10 = 120

Ответы [ 3 ]

0 голосов
/ 14 июня 2019

Если у вас версия 12c или выше:

with t( A,B, dte ) as
(
 select null, 20, date'2019-06-14' from dual union all
 select null, 40, date'2019-06-13' from dual union all
 select 10   ,50, date'2019-06-12' from dual
)
select * from t
match_recognize(
  order by dte desc
  measures
    nvl(
      first(a),
      y.a + sum(b)
    ) as a,
    first(b) as b,
    first(dte) as dte
  after match skip to next row
  pattern(x* y{0,1})
  define x as a is null,
    y as a is not null
);

     A          B DTE       
------ ---------- ----------
   120         20 2019-14-06
   100         40 2019-13-06
    10         50 2019-12-06
0 голосов
/ 14 июня 2019

Используйте условный подсчет для разделения данных на отдельные группы, затем используйте эту группу для аналитического расчета:

select a, b, dt, grp, sum(nvl(a, 0) + nvl(b, 0)) over (partition by grp order by dt) val
  from (
    select a, b, dt, count(case when a is not null then 1 end) over (order by dt) grp
      from t order by dt desc)
  order by dt desc

Результат выборки:

     A          B DT                 GRP        VAL
------ ---------- ----------- ---------- ----------
               20 2019-06-14           4        120
               40 2019-06-13           4        100
    10         50 2019-06-12           4         60
     5          2 2019-06-11           3          7
     6          1 2019-06-10           2          7
                3 2019-06-09           1         14
     7          4 2019-06-08           1         11

демо

0 голосов
/ 14 июня 2019

Я думаю, что то, что вы хотите, обрабатывается с помощью

sum(<column>) over (...) вместе с функцией last_value over (...), как показано ниже:

with t( A,B, "date" ) as
(
 select null, 20, date'2019-06-14' from dual union all
 select null, 40, date'2019-06-13' from dual union all
 select 10   ,50, date'2019-06-12' from dual
)
select nvl(a,sum(b) over (order by 1)+
             last_value(a) ignore nulls
                    over (order by 1 desc)
          ) as a,
       b, "date" 
  from t; 

A   B   date
--- --  ----------
120 20  14.06.2019
120 40  13.06.2019
 10 50  12.06.2019

Демо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...