Я не думаю, что вы можете сделать это с помощью оконных функций, увы. Проблема заключается в том, что заглавные буквы вводят изменение состояния, поэтому вы должны постепенно обрабатывать строки, чтобы получить значение для данной строки.
Рекурсивный CTE выполняет итерацию, поэтому он может делать то, что вы хотите:
with t as (
select t.*,
row_number() over (partition by id1, id2 order by date) as seqnum
from <yourtable> t
),
cte as (
select id1, id2, date, count,
(case when count < 0 then 0
when count > 8 then 8
else count
end) as runningsum,
seqnum
from t
where seqnum = 1
union all
select cte.id1, cte.id2, t.date, t.count,
(case when t.count + cte.runningsum < 0 then 0
when t.count + cte.runningsum > 8 then 8
else t.count + cte.runningsum
end) as runningsum, t.seqnum
from cte join
t
on t.seqnum = cte.seqnum + 1 and
t.id1 = cte.id1 and t.id2 = cte.id2
)
select *
from cte
order by id1, id2, date;
Здесь - это db <> fiddle.
Обратите внимание, что очень похожий код будет работать в Oracle 12C, который поддерживает рекурсивные CTE. В более ранних версиях Oracle вы можете использовать connect by
.