我在列中用逗号分隔数据:
Column
-------
a,b,c,d
我想将逗号分隔的数据分成多列以获取此输出:
Column1 Column2 Column3 Column4
------- ------- ------- -------
a b c d
如何做到这一点?
Answers:
如果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列。您应该使用数组列或单独的表。
string_to_array
在我的选项中添加一个,不确定我是怎么错过的。
split_part
过吗?只是好奇。
split_part()
一步就能完成您想要的工作:
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;
添加尽可能多的行col
(可能的最大值)。超出数据项的列将为空字符串(''
)。
string_to_array
使正则表达式费用无效。
string_to_array
使正则表达式费用无效。但是对于一手充满价值的手来说,这仍然要快得多。请参阅上面
您可以使用拆分功能。
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
string_to_array
代替regexp_split_to_array
; 它应该更快,因为它没有正则表达式处理的开销。