1. ホーム
  2. postgresql

[解決済み] カンマで区切られた列のデータを、さらに別の列に分割する

2023-07-02 11:58:43

質問

カラムにカンマ区切りのデータが入っています。

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

カンマで区切られたデータを複数の列に分割して、このような出力を得たいのですが。

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

どうすれば実現できるのか?

どのように解決するのですか?

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つのクエリを1つの関数にまとめることができます。

例えば、このようなデータを与えてみましょう(最後の行が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);

おかげさまで マイケル に感謝します。

可能な限り CSV カラムを使用しないように、データベース スキーマを再設計する必要があります。代わりに配列カラムまたは別のテーブルを使用すべきです。