Само с малко усилия. Нещо подобно:
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 ??;
Това изчислява текущата дължина и агрегира само стойности, които не надвишават дължината. ??
е каквото и да използвате за агрегиране. Това предполага, че line
е уникален, така че order by
е стабилен.
Това няма да включва impression
което надвишава дължината -- и нищо след това. Не прекъсва впечатлението. Тази логика е възможна, но усложнява заявката.