Dividi i dati delle colonne separati da virgola in colonne aggiuntive

Ho dati separati da virgole in una colonna:

Column ------- a,b,c,d 

Voglio dividere i dati separati da virgola in più colonne per ottenere questo risultato:

 Column1 Column2 Column3 Column4 ------- ------- ------- ------- abcd 

Come può essere realizzato?

Se il numero di campi nel CSV è costante, puoi fare qualcosa del genere:

 select a[1], a[2], a[3], a[4] from ( select regexp_split_to_array('a,b,c,d', ',') ) as dt(a) 

Per esempio:

 => select a[1], a[2], a[3], a[4] from (select regexp_split_to_array('a,b,c,d', ',')) as dt(a); a | a | a | a ---+---+---+--- a | b | c | d (1 row) 

Se il numero di campi nel CSV non è costante, è ansible ottenere il numero massimo di campi con qualcosa del genere:

 select max(array_length(regexp_split_to_array(csv, ','), 1)) from your_table 

quindi creare l’appropriato elenco a[1], a[2], ..., a[M] per la query. Quindi se quanto sopra ti ha dato un massimo di 6, dovresti usare questo:

 select a[1], a[2], a[3], a[4], a[5], a[6] from ( select regexp_split_to_array(csv, ',') from your_table ) as dt(a) 

È ansible combinare queste due query in una funzione, se lo si desidera.

Ad esempio, dai questo dato (che è un NULL nell’ultima riga):

 => select * from csvs; csv ------------- 1,2,3 1,2,3,4 1,2,3,4,5,6 (4 rows) => select max(array_length(regexp_split_to_array(csv, ','), 1)) from csvs; max ----- 6 (1 row) => select a[1], a[2], a[3], a[4], a[5], a[6] from (select regexp_split_to_array(csv, ',') from csvs) as dt(a); a | a | a | a | a | a ---+---+---+---+---+--- 1 | 2 | 3 | | | 1 | 2 | 3 | 4 | | 1 | 2 | 3 | 4 | 5 | 6 | | | | | (4 rows) 

Poiché il delimitatore è una semplice stringa fissa, potresti anche utilizzare string_to_array invece di regexp_split_to_array :

 select ... from ( select string_to_array(csv, ',') from csvs ) as dt(a); 

Grazie a Michael per il promemoria su questa funzione.

Dovresti davvero ridisegnare lo schema del tuo database per evitare la colonna CSV se ansible. Dovresti utilizzare invece una colonna di array o una tabella separata.

split_part() fa ciò che vuoi in un solo passaggio:

 SELECT split_part(col, ',', 1) AS col1 , split_part(col, ',', 2) AS col2 , split_part(col, ',', 3) AS col3 , split_part(col, ',', 4) AS col4 FROM tbl; 

Aggiungi tante linee quante ne hai in col (il massimo ansible). Le colonne che superano gli elementi di dati saranno stringhe vuote ( '' ).

Puoi usare la funzione split.

  SELECT (select top 1 item from dbo.Split(FullName,',') where id=1 ) Column1, (select top 1 item from dbo.Split(FullName,',') where id=2 ) Column2, (select top 1 item from dbo.Split(FullName,',') where id=3 ) Column3, (select top 1 item from dbo.Split(FullName,',') where id=4 ) Column4, FROM MyTbl