Oracle
 sql >> Database >  >> RDS >> Oracle

Dividi i valori separati da virgole in colonne in Oracle

Attenzione! L'espressione regexp_substr del formato '[^,]+' non restituirà il valore previsto se è presente un elemento null nell'elenco e si desidera quell'elemento o uno dopo di esso. Considera questo esempio in cui il 4° elemento è NULL e voglio il 5° elemento e quindi mi aspetto che venga restituito il "5":

SQL> select regexp_substr('1,2,3,,5,6', '[^,]+', 1, 5) from dual;

R
-
6

Sorpresa! Restituisce il 5° elemento NON-NULL, non il 5° elemento effettivo! Sono stati restituiti dati errati e potresti anche non prenderli. Prova invece questo:

SQL> select regexp_substr('1,2,3,,5,6', '(.*?)(,|$)', 1, 5, NULL, 1) from dual;

R
-
5

Quindi, il REGEXP_SUBSTR corretto sopra dice di cercare la 5a occorrenza di 0 o più caratteri delimitati da virgole seguiti da una virgola o dalla fine della riga (consente il separatore successivo, sia esso una virgola o la fine della riga) e quando trovato restituisce il 1° sottogruppo (i dati NON includono la virgola o la fine della riga).

Il modello di corrispondenza della ricerca '(.*?)(,|$)' spiegato:

(             = Start a group
.             = match any character
*             = 0 or more matches of the preceding character
?             = Match 0 or 1 occurrences of the preceding pattern
)             = End the 1st group
(             = Start a new group (also used for logical OR)
,             = comma
|             = OR
$             = End of the line
)             = End the 2nd group

EDIT:sono state aggiunte ulteriori informazioni e semplificate la regex.

Vedi questo post per maggiori informazioni e un suggerimento per incapsularlo in una funzione per un facile riutilizzo:REGEX per selezionare l'ennesimo valore da un elenco, consentendo nullsÈ il post in cui ho scoperto il formato '[^,]+' ha il problema. Sfortunatamente è il formato regex che vedrai più comunemente come risposta alle domande su come analizzare un elenco. Rabbrividisco al pensiero di tutti i dati errati restituiti da '[^,]+' !