Эту проблему легко решить, используя Оконные агрегаты , поддерживаемые в Firebird 3:
select *
,case when cumulative_qty <= sold_qty then qty
when sold_qty-(cumulative_qty - qty) < 0 then 0
else sold_qty-(cumulative_qty - qty)
end as qty_sold
,case when cumulative_qty <= sold_qty then qty
when sold_qty-(cumulative_qty - qty) < 0 then 0
else sold_qty-(cumulative_qty - qty)
end * price as value_sold
from
(
select *
,150 as sold_qty
-- cumulative sum of quantity in stock (FIFO)
,sum(qty) over (order by date rows unbounded preceding) as cumulative_qty
from tab
) as dt
;
Теперь вы можете вычислить сумму:
select
sum(case when cumulative_qty <= sold_qty then qty
when sold_qty-(cumulative_qty - qty) < 0 then 0
else sold_qty-(cumulative_qty - qty)
end) as qty_sold
,sum(case when cumulative_qty <= sold_qty then qty
when sold_qty-(cumulative_qty - qty) < 0 then 0
else sold_qty-(cumulative_qty - qty)
end * price) as value_sold
from
(
select *
,150 as sold_qty
-- cumulative sum of quantity in stock (FIFO)
,sum(qty) over (order by date rows unbounded preceding) as cumulative_qty
from tab
) as dt
;
См. db <> fiddle (с использованием Postgres, но синтаксис Firebird должен быть таким же)