Если количество полей в CSV постоянен, то вы могли бы сделать что-то вроде этого:
select a[1], a[2], a[3], a[4]
from (
select regexp_split_to_array('a,b,c,d', ',')
) as dt(a)
Например:
=> 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)
Если число полей в CSV не является постоянной то вы можете получить максимальное количество полей с чем-то вроде этого:
select max(array_length(regexp_split_to_array(csv, ','), 1))
from your_table
, а затем b uild соответствующий список столбцов a[1], a[2], ..., a[M]
для вашего запроса. Таким образом, если выше дал вам максимум 6, вы бы использовать это:
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)
Вы могли бы объединить эти два запроса в функцию, если вы хотите.
Например, дать эти данные (это NULL в последней строке):
=> 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)
Поскольку ваш разделителем является простой фиксированной строкой, вы можете также использовать string_to_array
вместо regexp_split_to_array
:
select ...
from (
select string_to_array(csv, ',')
from csvs
) as dt(a);
Благодаря Michael для напоминания об этой функции.
Вы действительно должны перепроектировать схему базы данных, чтобы избежать столба CSV, если это вообще возможно. Вместо этого вы должны использовать столбец массива или отдельную таблицу.
Благодаря должен проверить и восстановить – Gallop
Рассмотрите возможность использования 'string_to_array' вместо' regexp_split_to_array'; он должен быть быстрее, поскольку он не имеет накладных расходов на обработку регулярных выражений. – Michael
@Michael Вы могли бы добавить это как еще один ответ, если хотите. Или я мог бы добавить 'string_to_array' в качестве опции в мой, не уверенный, как я пропустил это. –