2011-09-09 18 views
6

Próbuję uzyskać nth element w ciągu oddzielane przecinkami za pomocą SQL w Oracle.Oracle SQL uzyskuje nge element regexp

Mam następujący tak daleko ..

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

ale to nie działa, gdy element jest pusty tzn ,, może ktoś pomóc?

+4

Gdy zobaczysz CSV lub inne wartości serializowane w RDBMS, wiesz, że coś jest nie tak. – NullUserException

+2

@NullUserException, dobry punkt. Niestety natknąłem się na to zbyt wiele razy :-( – Ollie

Odpowiedz

4

Jeśli wyznaczone wartości są zawsze alfanumerycznych pomiędzy przecinkami wtedy można spróbować:

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

Aby uzyskać wartość siódmy (łącznie z przecinkiem krocząca). Jeśli jest pusty, po prostu dostajesz przecinek końcowy (który możesz łatwo usunąć).

Oczywiście, jeśli chcesz mieć wartość inną niż siódma, zmień wartość czwartego parametru na dowolne wystąpienie np.

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

EDIT: Ponieważ kocham REGEX tutaj jest rozwiązanie, które usuwa również spływu przecinek

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

nadzieję, że pomoże

+0

+1, to działa – DCookie

+0

Witaj Ollie, mam ten sam problem, ale twoja rada nie działa w mojej sprawie Potrzebuję wziąć 3. wartość od ciągu 'wybierz regexp_substr ('SENDER, 3B13, 3, 300,,,,,,,', '[[: alnum:]] {0,},', 1, 2) z podwójnego;' ale otrzymuję tylko * *, ** string. Czy możesz mi doradzić, co robię źle? –

1

Można to zrobić mały trick: najpierw zastępując wszystkie przecinki przecinkiem, po którym następuje spacja, a następnie pomiń dodatkową przestrzeń wiodącą:

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 

Regar ds,
Rob.

1

ile utkniesz na wyrażeniach regularnych, jak to działa dobrze:

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 

Inną możliwością. Nie określiłeś źródła danych. Czy możesz ewentualnie użyć zewnętrznej tabeli, aby odczytać źródło wejściowe i przetworzyć je za pomocą SQL?

+0

Czy wystąpiłby problem związany z wywołaniem instrukcji trzy razy w instrukcji, a nie wywołaniem tylko REGEXP_SUBSTR? (zdaję sobie sprawę z długości ograniczonego łańcucha znaków został określony i byłby czynnikiem.) – Ollie

+0

@Ollie, to może, tylko mierząc wyniki, wiesz na pewno.RegexP_ * funkcje nie są bez własnych napowietrznych problemów. – DCookie

0
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;