Eu não acho que isso possa ser feito usando código baseado em conjunto, pois você precisa ler adiante e ler de volta. Algo processual poderia funcionar. Usando um cursor e uma tabela temporária, posso fazer isso (você precisa adicionar coisas para garantir que o saldo cumulativo não fique negativo). Pelo que você diz, a primeira transação nunca pode levar o saldo negativo, mas eu verificaria isso. Observe bem que os ganhos do pool de crédito podem vir de uma data posterior ao débito que o take está compensando - já que o saldo nunca pode ficar negativo, isso não deve ser um problema (sic). E é claro que eu não esperaria o desempenho para ser grande.
DROP TABLE IF EXISTS T;
create table t
(trx_no int, trx_date date, Opening int,debit int, credit int);
insert into t values
(1 , '2019-10-01' , 200 , 0 , 100),
(2 , '2019-10-02' , 200 , 0 , 100),
(3 , '2019-10-03' , 200 , 100 , 0 ),
(4 , '2019-10-03' , 200 , 400 , 0 ),
(5 , '2019-10-03' , 200 , 0 , 200),
(6 , '2019-10-04' , 200 , 0 , 100),
(7 , '2019-10-05' , 200 , 100 , 0 ),
(8 , '2019-10-05' , 200 , 0 , 400);
DROP TABLE IF EXISTS stmT;
create table stmt
(trx_no int, trx_date date, Opening int,debit int, credit int, cumbal int);
drop procedure if exists p;
delimiter $$
create procedure p()
begin
declare v_trx_no int;
declare v_dt date;
declare v_debit int;
declare v_credit int;
declare h_trx_no int;
declare h_dt date;
declare h_credit int;
declare opbal int;
declare rbal int;
declare done int default 0;
declare cur cursor for select trx_no,trx_date,debit,credit from t order by trx_date,trx_no;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
select opening into opbal from t order by trx_no limit 1;
set rbal = opbal;
drop table if exists creditpool;
create temporary table if not exists creditpool as select trx_no,trx_date,credit,0 as used from t where credit > 0;
#select * from creditpool;
open cur;
cursorloop:loop
fetch cur into v_trx_no,v_dt,v_debit,v_credit;
if done = true then
leave cursorloop;
end if;
if v_credit > 0 and exists (select 1 from creditpool where trx_no = v_trx_no and used = 0) then
if v_credit > 0 then
insert into stmt values (v_trx_no,v_dt,opbal,v_debit,v_credit, rbal + v_credit);
set rbal = rbal + v_credit;
update creditpool set used = 1 where trx_no = v_trx_no;
end if;
end if;
if v_debit > 0 and v_debit <= rbal then
insert into stmt values (v_trx_no,v_dt,opbal,v_debit,v_credit, rbal - v_debit);
set rbal = rbal - v_debit;
elseif v_debit > 0 and v_debit > rbal then
poolloop: loop
select trx_no,trx_date,credit
into h_trx_no,h_dt,h_credit
from creditpool
where used = 0
order by trx_date,trx_no limit 1;
insert into stmt values (h_trx_no,h_dt,opbal,0,h_credit, rbal + h_credit);
set rbal = rbal + h_credit;
update creditpool set used = 1 where trx_no = h_trx_no;
if v_debit <= rbal then
insert into stmt values (v_trx_no,v_dt,opbal,v_debit,v_credit, rbal - v_debit);
set rbal = rbal - v_debit;
leave poolloop;
end if;
end loop poolloop;
end if;
end loop cursorloop;
close cur;
end $$
delimiter ;
truncate stmt;
call p();
select * from stmt;
+--------+------------+---------+-------+--------+--------+
| trx_no | trx_date | Opening | debit | credit | cumbal |
+--------+------------+---------+-------+--------+--------+
| 1 | 2019-10-01 | 200 | 0 | 100 | 300 |
| 2 | 2019-10-02 | 200 | 0 | 100 | 400 |
| 3 | 2019-10-03 | 200 | 100 | 0 | 300 |
| 5 | 2019-10-03 | 200 | 0 | 200 | 500 |
| 4 | 2019-10-03 | 200 | 400 | 0 | 100 |
| 6 | 2019-10-04 | 200 | 0 | 100 | 200 |
| 7 | 2019-10-05 | 200 | 100 | 0 | 100 |
| 8 | 2019-10-05 | 200 | 0 | 400 | 500 |
+--------+------------+---------+-------+--------+--------+
8 rows in set (0.00 sec)
Observe que o resultado é um pouco diferente do resultado desejado porque uma tomada ocorre apenas quando necessário.