Se il numero di campi nel CSV è costante, allora si potrebbe fare qualcosa di simile:
select a[1], a[2], a[3], a[4]
from (
select regexp_split_to_array('a,b,c,d', ',')
) as dt(a)
Ad 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 quindi è possibile ottenere il numero massimo di campi con qualcosa del genere:
select max(array_length(regexp_split_to_array(csv, ','), 1))
from your_table
e quindi b uild l'appropriato elenco di colonne a[1], a[2], ..., a[M]
per la tua query. Quindi, se il sopra ti ha dato un massimo di 6, devi 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)
è possibile combinare queste due domande in una funzione se si voleva.
Per esempio, dare questi dati (che è un NULL in ultima fila):
=> 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)
Dal momento che il delimitatore è una semplice stringa fissa, si potrebbe anche usare 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.
Si dovrebbe davvero ridisegnare lo schema del database per evitare la colonna CSV se possibile. Dovresti utilizzare invece una colonna di array o una tabella separata.
Grazie devono controllare e ripristinare – Gallop
Considerare l'utilizzo di 'string_to_array' invece di' regexp_split_to_array'; dovrebbe essere più veloce poiché non ha il sovraccarico di elaborazione di espressioni regolari. – Michael
@ Michael Puoi aggiungere un'altra risposta, se lo desideri. Oppure potrei aggiungere 'string_to_array' come opzione al mio, non so come mi sia mancato. –