如果 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
然后为您的查询构建适当的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 列。您应该改用数组列或单独的表。