首页 > 解决方案 > 将一列拆分为多列(数量和名称未知)

问题描述

考虑我有一个这样的表:

示例

ID    Name    Something    Params
-----------------------------------------
1     First   A241FRT      P1=12, P2=One
2     Second  G924PEM      P1=19
3     Third   L9449TY      P1=94, P2=Two

我需要将列拆分Params为多个。所以我需要得到这样的东西:

预期结果

ID    Name    Something    P1    P2
-----------------------------------------
1     First   A241FRT      12    One
2     Second  G924PEM      19
3     Third   L9449TY      94    Two

我不知道额外列的名称以及数量。
我不是很擅长 SQL,所以我非常需要你的帮助,谢谢大家

标签: sqlpostgresql

解决方案


我会将参数转换为 json 值,然后提取键:

select id, name, something, 
       params ->> 'P1' as p1,
       params ->> 'P2' as p2
from (
  select id, 
         name, 
         something, 
         concat('{', 
                  regexp_replace(regexp_replace(params, '(P[0-9])=', '"\1":', 'gi'), 
                                 ':(\w+)', ':"\1"', 'gi'), 
                '}')::jsonb
  from the_table
) t

如果您经常需要,创建一个将“参数”转换为 JSON 表示的函数可能是有意义的:

create function params_to_json(p_params text)
  returns jsonb
as
$$
  select jsonb_object_agg(split_part(p, '=', 1), split_part(p, '=', 2))
  from regexp_split_to_table(p_params, ',\s*') as t(p)
$$
language sql
stable
;           

然后你可以像这样使用它:

select id, name, something, 
       params_to_json(params) ->> 'P1' as p1,
       params_to_json(params) ->> 'P2' as p2
from data

该函数对于未知键更加灵活,因为它只假设键/值对由 a 分隔,,并且键和值由 a 分隔=


推荐阅读