Вы можете использовать функцию Oracles LAG для доступа к предыдущему ряду ( ссылка ). Остальное - большой оператор CASE, обрабатывающий различные состояния.
В моем примере ниже я предполагаю, что столбцы ID и DATE являются первичными ключами в демонстрационной таблице. Вы должны проверить части, где NULL используется для CAL C (отмечено 2 знаками вопроса). Это состояния не определены вашим описанием.
BEGIN
EXECUTE IMMEDIATE 'drop table table_a';
EXCEPTION
WHEN OTHERS THEN NULL;
END;
/
create table table_a (
"ID" number,
"PER" number,
"DATE" date,
"CALC" number
);
/
insert into table_a
select 1 "ID", 11 "PER", trunc(sysdate)-1 "DATE", null "CALC" from dual
union all
select 1 "ID", 6 "PER", trunc(sysdate) "DATE", null "CALC" from dual
union all
select 2 "ID", 7 "PER", trunc(sysdate)-1 "DATE", null "CALC" from dual
union all
select 2 "ID", 12 "PER", trunc(sysdate) "DATE", null "CALC" from dual
union all
select 3 "ID", 13 "PER", trunc(sysdate) "DATE", null "CALC" from dual
union all
select 4 "ID", 8 "PER", trunc(sysdate) "DATE", null "CALC" from dual
/
update table_a
set ("CALC") = (
with tmp_prev as (
select
"ID",
"PER",
"DATE",
LAG("PER") OVER (PARTITION BY "ID" ORDER BY "ID","DATE") "PREV_PER"
from table_a
)
select
case when "PREV_PER" is null
then
case when "PER" > 10 then 1
else
case when "PER" > 5 and "PER" < 10
then 2
else null -- ?? =10 or <=5
end
end
else
case when "PER" > "PREV_PER"
then 3
else
case when "PER" < "PREV_PER"
then 4
else null -- ?? equal
end
end
end calc_new
from tmp_prev
where table_a."ID"=tmp_prev."ID" and table_a."DATE"=tmp_prev."DATE"
);
/
select * from table_a;
/
Результат:
ID PER DATE CALC
---------- ---------- -------- ----------
1 11 02.05.20 1
1 6 03.05.20 4
2 7 02.05.20 2
2 12 03.05.20 3
3 13 03.05.20 1
4 8 03.05.20 2