【问题标题】:Split a column using a delimiter coma and rename based on the same column in postgres使用分隔符逗号拆分列并根据 postgres 中的同一列重命名
【发布时间】:2021-03-02 23:58:25
【问题描述】:

我有一个带有列配置的表,我想拆分配置列并根据同一列上的值创建新列

company         config
   A    User:xxx,Key:ABC,Role:admin
   B    User:yyy,Key:CTA,Role:Hr,Location:New York
   C    User:zzz,Location:London,Status:Active

预期输出

company  User   Key   Role   Location   Status
A        xxx    ABC   admin
B        yyy    CTA    Hr    New York
C        zzz                 London     Active

【问题讨论】:

  • 老实说,这种清理方式最适合使用 Postgres 的应用程序语言(例如 Java、C#、Python 等)。数据库的设计并没有真正考虑到这种任务。您应该首先规范化您的数据(即在此处以您实际想要的格式获取它),然后导入 Postgres。
  • 如果由于某种原因您无法规范化数据,您至少应该考虑将其存储为 JSON 值,以便您可以轻松访问每个键。

标签: sql string postgresql csv lateral-join


【解决方案1】:

这是一个非常糟糕的数据设计。但是 Postgres 有强大的字符串函数。你可以这样做:

select t.company,
    max(y.v) filter(where y.k = 'User')     as "user",
    max(y.v) filter(where y.k = 'Key')      as "key",
    max(y.v) filter(where y.k = 'Role')     as "role",
    max(y.v) filter(where y.k = 'Location') as location,
    max(y.v) filter(where y.k = 'Status')   as status
from mytable t
cross join lateral regexp_split_to_table(t.config, ',') x(val)
cross join lateral (values (split_part(x.val, ':', 1), split_part(x.val, ':', 2)) y(k, v)
group by t.company

这首先将 CSV 列表转换为行,然后提取键/值对。最后一步是条件聚合,因此为每一列分配值。

【讨论】:

    【解决方案2】:

    我可能会编写一个函数来将其转换为更“可解析”的格式:

    create function convert_to_json(p_config text)
      returns jsonb
    as
    $$
      select jsonb_object_agg(items[1], items[2])
      from (
        select string_to_array(x.item, ':') items
        from unnest(string_to_array(p_config, (','))) x(item)
      ) t
    $$
    language sql 
    immutable;
    

    该函数不正确处理值中嵌入的逗号,例如如果你有类似User: "Dent, Arthur"

    那么你可以这样使用它:

    select company, 
           json_config ->> 'Key' as "Key",
           json_config ->> 'User' as "User",
           json_config ->> 'Role' as "Role",
           json_config ->> 'Location' as "Location",
           json_config ->> 'Status' as "Status"
    from (       
      select company, convert_to_json(config) as json_config
      from the_table
    ) t
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多