Kun med en smule indsats. Noget som dette:
select listagg((case when running_len < 4000 then oi.impression end), ',') within group (order by oi.line)
from (select oi.*,
sum(length(oi.impression) + 1) over (partition by ?? order by oi.line) as running_len
from order_impression oi
) oi
group by ??;
Dette beregner løbelængden og samler kun værdier, der ikke overstiger længden. ??
er hvad end du bruger til aggregering. Dette forudsætter, at line
er unik, så order by
er stabil.
Dette inkluderer ikke impression
der overstiger længden -- og intet efter det. Det skærer ikke indtrykket af. Den logik er mulig, men den komplicerer forespørgslen.