Чтобы ответить на ваш вопрос, вы запрашиваете список, в котором он соответствует подэлементу, и это произойдет только там, где список состоит из одного элемента. То, что вы действительно хотели выбрать, - это сами подэлементы.
Примечание: Объяснение того, почему при разборе строки, используя форму регулярных выражений '[^_]+'
плохо здесь: https://stackoverflow.com/a/31464699/2543416
Вы хотите, чтобы разобрать список, выбирая элементы:
SQL> with TVL_DETAIL(TVL_CD_LIST) as (
select 'M1180_Z6827' from dual union
select 'K5900_Z6828' from dual union
select 'I2510' from dual
)
SELECT distinct regexp_substr(TVL_CD_LIST, '(.*?)(_|$)', 1, level, NULL, 1) element
FROM TVL_DETAIL
CONNECT BY level <= LENGTH(regexp_replace(TVL_CD_LIST, '[^_]', '')) + 1;
-- 11g CONNECT BY level <= regexp_count(TVL_CD_LIST, '_') + 1;
ELEMENT
-----------
Z6827
K5900
M1180
I2510
Z6828
SQL>
И это здорово, если вы хотите для отслеживания строки и элемента внутри строки:
SQL> with TVL_DETAIL(row_nbr, TVL_CD_LIST) as (
select 1, 'M1180_Z6827' from dual union
select 2, 'K5900_Z6828' from dual union
select 3, 'I2510' from dual
)
SELECT row_nbr, column_value substring_nbr,
regexp_substr(TVL_CD_LIST, '(.*?)(_|$)', 1, column_value, NULL, 1) element
FROM TVL_DETAIL,
TABLE(
CAST(
MULTISET(SELECT LEVEL
FROM dual
CONNECT BY level <= LENGTH(regexp_replace(TVL_CD_LIST, '[^_]', '')) + 1
-- 11g CONNECT BY LEVEL <= REGEXP_COUNT(TVL_CD_LIST, '_')+1
) AS sys.OdciNumberList
)
)
order by row_nbr, substring_nbr;
ROW_NBR SUBSTRING_NBR ELEMENT
---------- ------------- -----------
1 1 M1180
1 2 Z6827
2 1 K5900
2 2 Z6828
3 1 I2510
SQL>
EDIT: к сожалению, отредактированный для работы с 10g как REGEXP_COUNT не доступен до 11g.
Благодаря Gary_W ... так что, когда я выполнить запрос, я получаю эту ошибка: ORA-00939: слишком много аргументов для функции – user3666552
Проверьте синтаксис тщательно, как вы может видеть, что это сработало для меня. –