Регулярное выражение с Connect by - PullRequest
0 голосов
/ 26 июня 2019

У меня есть этот запрос:

select regexp_substr('1,2,3,4,5','[^,]+',1,level) 
from test1 
connect by instr('1,2,3,4,5',',',1,level-1)>0;

Пожалуйста, помогите мне разобраться в этом запросе, особенно об использовании уровня и подключении и уровне-1.

Ответы [ 2 ]

0 голосов
/ 27 июня 2019

@ Ответ Вернфрида превосходен, но вы должны знать, что существует большой риск с регулярным выражением формата '[^,]+', которое часто рассматривается как пример того, как анализировать строки с разделителями.

Это работает толькокогда все элементы списка присутствуют.Чтобы открыть глаза, попробуйте со вторым элементом как NULL:

select regexp_substr('1,,3,4,5', '[^,]+', 1, 3) from dual;

REGEXP_SUBSTR('1,,3,4,5','[^,]+',1,3)
-------------------------------------
4   

1 row selected.

ЧТО?'4' определенно НЕ 3-й элемент этого списка!Как вы можете видеть, NULL не обрабатывается.

Пожалуйста, используйте этот формат REGEXP_SUBSTR, который обрабатывает элементы списка NULL:

select regexp_substr('1,,3,4,5','(.*?)(,|$)', 1, 3, NULL, 1) from dual;


REGEXP_SUBSTR('1,,3,4,5','(.*?)(,|$)',1,3,NULL,1)
-------------------------------------------------
3              

1 row selected.

Регулярное выражение определяет 2 группы, необязательный наборлюбых символов, за которыми следует запятая или конец строки.Аргументы REGEXP_SUBSTR говорят, что нужно вернуть 1-ю группу 3-го экземпляра этого совпадения.

0 голосов
/ 26 июня 2019

LEVEL и CONNECT BY используются для генерации последовательностей, см. Этот простой пример:

select level
from dual
connect by level < 10;

LEVEL
=======
1
2
3
4
5
6
7
8
9

instr('1,2,3,4,5', ',' , 1, level-1) > 0 подсчитывает количество элементов, разделенных запятой, возможно, эту версию легче понять, она делает то же самое:

select regexp_substr('1,2,3,4,5','[^,]+',1,level) 
from dual 
connect by LEVEL <= REGEXP_COUNT('1,2,3,4,5', ',')+1;

LEVEL <= REGEXP_COUNT('1,2,3,4,5', ',')+1 или instr('1,2,3,4,5', ',' , 1, level-1) > 0 означает «выполнить пять раз».

Таким образом, ваш выбор по сути является ярлыком для

select regexp_substr('1,2,3,4,5','[^,]+', 1, 1) from dual union all 
select regexp_substr('1,2,3,4,5','[^,]+', 1, 2) from dual union all 
select regexp_substr('1,2,3,4,5','[^,]+', 1, 3) from dual union all 
select regexp_substr('1,2,3,4,5','[^,]+', 1, 4) from dual union all 
select regexp_substr('1,2,3,4,5','[^,]+', 1, 5) from dual;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...