select * from (
select regexp_substr('D01,D08,D02,D05,D10,D11,D12,D20,D21,D22,D30,D31','[^,]+', 1, level) as split from dual
connect by regexp_substr('D01,D08,D02,D05,D10,D11,D12,D20,D21,D22,D30,D31', '[^,]+', 1, level) is not null
) order by split asc
ВЫВОД:
SPLIT
D01
D02
D03
D04
D10
D11
D12
D20
D21
D22
D30
D31
Ссылка на fiddle
Хорошее объяснение REGEXP_SUBSTR
можно найти here.
Хорошее объяснение connected by
можно найти here
Краткое объяснение:
select regexp_substr('D01,D08,D02,D05,D10,D11,D12,D20,D21,D22,D30,D31','[^,]+', 1, 1) as split from dual
возвращает первый матч подстроки D01
. Если изменить последний параметр 2:
select regexp_substr('D01,D08,D02,D05,D10,D11,D12,D20,D21,D22,D30,D31','[^,]+', 1, 2) as split from dual
он вернется второй матч: D08
и т.д.
Connected by
рекурсивно «заказные» элементы в соответствии с их «иерархии» (которая является порядок они появляются в строке - в нашем примере). Этот порядок можно просмотреть с помощью параметра level
. Изменение запроса:
select level, regexp_substr('D01,D08,D02,D05,D10,D11,D12,D20,D21,D22,D30,D31','[^,]+', 1, level) as split from dual
connect by regexp_substr('D01,D08,D02,D05,D10,D11,D12,D20,D21,D22,D30,D31', '[^,]+', 1, level) is not null
выхода будут подстрок в соответствии с их «уровнем»:
LEVEL SPLIT
1 D01
2 D08
3 D02
4 D05
5 D10
6 D11
7 D12
8 D20
9 D21
10 D22
11 D30
12 D31
После того как мы воспользовались этим уровнем, чтобы отобразить все подстроки рекурсивны, мы «обернуть» запрос с другим запросом - для order by
(естественный порядок строк).
Чтобы удовлетворить третье и последнее требование - вы должны «вырезать строку» после третьего появления «||», (подсказка: вы должны использовать другое регулярное выражение для '||' и условие: 'where level> ...') – alfasin