Дана строка, представляющая собой последовательность натуральных чисел, соединенных символом ';': '12;657;34;11;90;213;1221;227'
Написать запрос, который делает из нее строку, соединенную символами ',', но отсортированную по возрастанию.
Решаем задачу, воспользовавшись запросами, приведенными в главе ""Расклейка" и "Склейка" строк".
В подзапросе q1 получаем отсортированный расклеенный набор, который затем склеиваем:
select ids
from (select ltrim(sys_connect_by_path(id, ','), ',') as ids
from (select id, lag(id) over(order by id) as prev_id
from (select to_number(regexp_substr(s, '[^;]+', 1, level)) id
from (select '12;657;34;11;90;213;1221;227' s
from dual)
connect by regexp_substr(s, '[^;]+', 1, level) is not null
order by id) q1)
start with prev_id is null
connect by prev_id = prior id
order by level desc)
where rownum = 1;
Теперь усложним задачу. Допустим, во входных данных возможны повторения, например, '12;657;34;11;90;213;11;213'.
Отсортируем набор, дав каждому элементу свой уникальный номер (ordr) в отсортированном наборе:
select id, row_number() over(order by id) ordr
from (select to_number(regexp_substr(s, '[^;]+', 1, level)) id
from (select '12;657;34;11;90;213;11;213' s from dual)
connect by regexp_substr(s, '[^;]+', 1, level) is not null);
Воспользуемся этим запросом (в качестве подзапроса q1) для решения задачи. Иерархию раскручиваем по ordr вместо id:
select ids
from (select ltrim(sys_connect_by_path(id, ','), ',') as ids
from (select id, ordr, lag(ordr) over(order by ordr) as prev_ordr
from (select id, row_number() over(order by id) ordr
from (select to_number(regexp_substr(s,
'[^;]+',
1,
level)) id
from (select '12;657;34;11;90;213;11;213' s
from dual)
connect by regexp_substr(s, '[^;]+', 1, level) is not null)) q1)
start with prev_ordr is null
connect by prev_ordr = prior ordr
order by level desc)
where rownum = 1;