Oracle SQL получает n-й элемент regexp

Я пытаюсь получить n-й элемент в разделительной запятой, используя SQL в Oracle.

У меня есть следующее:

SELECT regexp_substr(
   '100016154,5101884LT00001,,,,,100000010892100000012655,L,SEI,5101884LT00001,1,SL,3595.03,00,2,N,N,G,N',
   '[^,]+',
   1,
   7)
FROM dual;

но он не работает, когда элемент пуст, т.е. может ли кто-нибудь помочь?

Ответ 1

Если ваши разделительные значения всегда будут буквенно-цифровыми между запятыми, вы можете попробовать:

SELECT REGEXP_SUBSTR( <delimied_string>, '[[:alnum:]]{0,},', 1, 7 )
  FROM dual;

Чтобы получить седьмое значение (включая конечную запятую). Если он пуст, вы просто получаете конечную запятую (которую вы можете легко удалить).

Очевидно, что если вам нужно значение, отличное от седьмого, измените значение четвертого параметра на любое значение nth, которое вы хотите, например.

SELECT REGEXP_SUBSTR( <delimied_string>, '[[:alnum:]]{0,},', 1, <nth occurance> )
  FROM dual;

EDIT: Поскольку я люблю REGEX, это решение, которое также удаляет конечную запятую

SELECT REPLACE(
          REGEXP_SUBSTR(<delimied_string>, '[[:alnum:]]{0,},', 1, <nth>), 
          ','
       )
  FROM dual;

надеюсь, что это поможет

Ответ 2

Вы можете сделать это с помощью небольшого трюка: сначала замените все запятые запятой, затем пробелом, а затем пропустите это дополнительное ведущее пространство:

SQL> with data as
  2  ( select '100016154,5101884LT00001,,,,,100000010892100000012655,L,SEI,5101884LT00001,1,SL,3595.03,00,2,N,N,G,N' txt
  3      from dual
  4  )
  5  select regexp_substr(txt,'[^,]+',1,7)                             seventh_element_wrong
  6       , replace(txt,',',', ')                                      with_extra_space_after_comma
  7       , regexp_substr(replace(txt,',',', '),'[^,]+',1,7)           seventh_element_leading_space
  8       , substr(regexp_substr(replace(txt,',',', '),'[^,]+',1,7),2) the_seventh_element
  9    from data
 10  /

S WITH_EXTRA_SPACE_AFTER_COMMA
- ----------------------------------------------------------------------------------------------------------------------
SEVENTH_ELEMENT_LEADING_S THE_SEVENTH_ELEMENT
------------------------- ------------------------
1 100016154, 5101884LT00001, , , , , 100000010892100000012655, L, SEI, 5101884LT00001, 1, SL, 3595.03, 00, 2, N, N, G, N
 100000010892100000012655 100000010892100000012655

С уважением,
Роб.

Ответ 3

Если вы не застряли в регулярных выражениях, это также работает:

WITH q AS (
SELECT '100016154,5101884LT00001,,,,,100000010892100000012655,L,SEI,5101884LT00001,1,SL,3595.03,00,2,N,N,G,N' thestring FROM dual
)
SELECT SUBSTR(thestring, INSTR(thestring,',',1,6)+1, 
                         INSTR(thestring,',',1,7)-INSTR(thestring,',',1,6)-1) "The Element"
  FROM q;

The Element
------------------------
100000010892100000012655

Другая возможность. Вы не указали, каков источник ваших данных. Не могли бы вы использовать внешнюю таблицу для чтения исходного источника и обработать его через SQL?

Ответ 4

SELECT rtrim(regexp_substr('100016154,5101884LT00001,,,,,100000010892100000012655,L,SEI,5101884LT00001,1,SL,3595.03,00,2,N,N,G,N','[^,]{0,}[,]?',1,7),',')
FROM dual;