使用新添加的列更新 table,其中包含来自相同 table 旧列的数据,但已修改(展平)jsonb

Update table with newly added column containing data from the same table old column, but modified (flattened) jsonb

所以我遇到了必须将数据从一列迁移到具有不同 jsonb 模式的自身“克隆”的问题 -> 我需要从中解析 json ["keynamed": [...{"type": "type_info", "value": "value_in_here"}]]使用 key:value 转换为普通对象 - 像 {"type_info": "value_in_here" ,...}

这样的字典

到目前为止,我已经尝试在子查询中使用子查询和 json 函数 + 切换大小写以将“type”映射到“type_info”,然后使用 jsonb_build_object(),但是这从 wole table 中获取数据,我需要用行中的数据更新它 - 有什么比做 N 个子查询更简单的方法吗?我最接近的方法是:

select 
  jsonb_object_agg(t.k, t.v):: jsonb as _json 
from 
  (
    select 
      jsonb_build_object(type_, _value) as _json 
    from 
      (
        select 
          _value, 
          CASE _type
              ...
          END type_ 
        from 
          (
            select 
              (datasets ->> 'type') as _type, 
              datasets -> 'value' as _value 
            from 
              (
                select 
                  jsonb_array_elements(
                    values 
                      -> 'keynamed'
                  ) as datasets 
                from 
                  table
              ) s
          ) s
      ) s
  ) s, 
  jsonb_each(_json) as t(k, v);

但我不知道如何使其成为特定行并应用于简单更新,例如:

UPDATE table
SET table.new_field = (subquery with parsed dict in json)

任何 ideas/tips 如何在没有任何外部支持的情况下使用普通 PSQL 解决它?

table 的预期输出为:

 id |      old_value                                 |                    new_value       
----------------+-------------------------------------+------------------------------------
 1  | ["keynamed": [...{"type": "type_info", "value": "value_in_here"}]] | {"type_info": "value_in_here" ,...}
 

根据 postgres 文档,您可以通过 select table 使用更新并使用连接模式 update document

样本:

UPDATE accounts SET contact_first_name = first_name,
                    contact_last_name = last_name
  FROM salesmen WHERE salesmen.id = accounts.sales_id;

如果我没理解错的话,下面的查询可以帮到你。但我无法测试,因为我没有样本数据,我不知道这个查询是否有语法错误。

update table t
set new_value = tmp._json
from (
select 
  id,
  jsonb_object_agg(t.k, t.v):: jsonb as _json 
from 
  (
    select 
      id,
      jsonb_build_object(type_, _value) as _json 
    from 
      (
        select 
          id,
          _value, 
          CASE _type
              ...
          END type_ 
        from 
          (
            select 
              id,
              (datasets ->> 'type') as _type, 
              datasets -> 'value' as _value 
            from 
              (
                select
                  id,
                  jsonb_array_elements(
                    values 
                      -> 'keynamed'
                  ) as datasets 
                from 
                  table
              ) s
          ) s
      ) s
  ) s, 
  jsonb_each(_json) as t(k, v)
  group by id) tmp
where tmp.id = t.id;