Tylko przy odrobinie wysiłku. Coś takiego:
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 ??;
To oblicza długość biegu i agreguje tylko wartości, które nie przekraczają długości. ??
to wszystko, czego używasz do agregacji. To zakłada, że line
jest unikalny, więc order by
jest stabilny.
Nie obejmuje to impression
która przekracza długość - i nic po tym. Nie obcina wrażenia. Taka logika jest możliwa, ale komplikuje zapytanie.