【问题标题】:How to get multiple comma-separated values as individual columns?如何将多个逗号分隔的值作为单独的列?
【发布时间】:2016-12-21 12:40:40
【问题描述】:

我有一张表格,里面有这样的数据:

select * from data

id |  col1 |  col2 |  col3
---+-------+-------+-------
 1 | 1,2,3 | 4,5,6 | 7,8,9

我想得到这样的数据:

id | name | dd | fn | suf
---+------+----+----+-----
1  | col1 |  1 |  2 |  3
1  | col2 |  4 |  5 |  6
1  | col3 |  7 |  8 |  9

目前,我在这样的查询中使用split_part()

SELECT * from(
select id,
       'col1' as name,
       NULLIF(split_part(col1, ',', 1), '') AS dd, 
       NULLIF(split_part(col1, ',', 2), '') AS fn, 
       NULLIF(split_part(col1, ',', 3), '') AS suf
       from data

       UNION 
       select id,
       'col2' as name,
       NULLIF(split_part(col2, ',', 1), '') AS dd, 
       NULLIF(split_part(col2, ',', 2), '') AS fn, 
       NULLIF(split_part(col2, ',', 3), '') AS suf
       from data
        UNION 
       select id,
       'col3' as name,
       NULLIF(split_part(col3, ',', 1), '') AS dd, 
       NULLIF(split_part(col3, ',', 2), '') AS fn, 
       NULLIF(split_part(col3, ',', 3), '') AS suf
       from data
);

有没有更优雅的方式? 我有 20 列

【问题讨论】:

  • 你应该使用 Postgres 函数split_part()
  • 看我的要求。
  • 您的表定义和 Postgres 版本会有所帮助。 col1col2col3的数据类型是text?或int[]?元素是整数值?最多3个元素?可以有 0 个元素(空字符串/数组)吗?想要的结果?缺少的元素会产生 NULL 值吗?

标签: sql postgresql split pivot delimiter


【解决方案1】:

假设这张表:

CREATE TABLE tbl (id int, col1 text, col2 text, col3 text);
INSERT INTO tbl VALUES (1 ,'1,2,3', '4,5,6', '7,8,9');

LATERAL 子查询中的 VALUES 表达式应该是一个优雅的解决方案。
然后只需使用split_part()。仅当源中可以有实际的空字符串时才添加NULLIF() ...

SELECT id, x.name
     , split_part(x.col, ',', 1) AS dd
     , split_part(x.col, ',', 2) AS fn
     , split_part(x.col, ',', 3) AS suf
FROM   tbl t, LATERAL (
   VALUES (text 'col1', t.col1)
        , (     'col2', t.col2)
        , (     'col3', t.col3)
        -- ... many more?
   ) x(name, col);

适用于 PostgreSQL 9.3 或更高版本。
SQL Fiddle.

相关:

【讨论】:

  • 名称列在哪里?
  • @PSM:我添加了name列。
  • 谢谢。你节省了我的时间。
【解决方案2】:

我会先做union all,然后再做split_part()

select id, name,
       coalesce(split_part(col, ',', 1), '') as dd,
       coalesce(split_part(col, ',', 2), '') as fn,
       coalesce(split_part(col, ',', 3), '') as suf
from ((select id, 'col1' as name, col1 as col from data
      ) union all
      (select id, 'col2' as name, col2 as col from data
      ) union all
      (select id, 'col3' as name, col3 as col from data
      )
     ) t;

【讨论】:

    猜你喜欢
    • 2014-11-15
    • 2023-03-22
    • 1970-01-01
    • 2012-01-28
    • 2017-02-05
    • 1970-01-01
    • 2017-03-17
    • 2021-05-29
    • 1970-01-01
    相关资源
    最近更新 更多