web-dev-qa-db-ja.com

カンマ区切りの列データを追加の列に分割します

列にコンマ区切りのデータがあります:

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

この出力を取得するには、コンマ区切りのデータを複数の列に分割します。

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

どうすればこれを達成できますか?

58
Gallop

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)

必要に応じて、これら2つのクエリを組み合わせて関数にすることができます。

たとえば、次のデータを指定します(最後の行の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列を回避する必要があります。代わりに、配列列または別のテーブルを使用する必要があります。

61
mu is too short

split_part() は、必要なことを1ステップで実行します。

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(可能な最大値)にあるアイテムと同じ数の行を追加します。データ項目を超える列は空の文字列('')。

89

分割機能を使用できます。

    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
1
vicky