80

我在一列中有逗号分隔的数据:

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

我想将逗号分隔的数据拆分为多列以获得此输出:

Column1  Column2 Column3 Column4 
-------  ------- ------- -------
a        b       c       d 

如何做到这一点?

4

3 回答 3

126

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(可能的最大值)。
超出数据项的列将是空字符串 ( '')。

于 2011-12-23T05:09:18.763 回答
89

如果 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 列。您应该改用数组列或单独的表。

于 2011-12-21T05:31:33.080 回答
0

您可以使用拆分功能。

    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
于 2017-01-09T12:36:41.887 回答