postgresql 使用复杂json中的where子句更新集合中的值- Postgres

2ekbmq32  于 2023-06-05  发布在  PostgreSQL
关注(0)|答案(1)|浏览(226)

我有一个PG表,其中有一个名为data的json字段,结构如下

{
  "location": "",
  "department": [],
  "languagesKnown": [
    "English,Spanish"
  ],
  "maritalStatus": "Single",
  "kidsCount": 0,
  "relations": [
    {
      "type": "father",
      "name": "somename",
      "status": "live"
    },
    {
      "type": "Mother",
      "name": "somename",
      "status": "Notlive"
    }
  ]
}

如何将状态值为“NotAlive”的所有关系更新为“No More”
PG版本:14

rdlzhqv9

rdlzhqv91#

可以使用jsonb_set

select col from (
  select col, jsonb_set(col, '{relations}', jsonb_agg(s.relation_updated)) as col_updated
  from (
    select *, jsonb_set(relation::jsonb, '{status}', 
              CASE
                 WHEN relation ->> 'status' = 'Notlive' THEN '"No More"'::jsonb
                 ELSE relation -> 'status'
               END) as relation_updated
    from mytable t,
         jsonb_array_elements(t.col->'relations') as relation
   ) as s
   group by col
) as s

1.使用jsonb_array_elements()提取所有数组元素,并使用jsonb_set()更新数组元素中的状态。CASE子句执行条件检查。
1.使用jsonb_agg将数组元素聚合到一个数组中
update语句可以是:

update mytable t
set col = u.col_updated 
from (
  select col, jsonb_set(col, '{relations}', jsonb_agg(s.relation_updated)) as col_updated
  from (
    select *, jsonb_set(relation::jsonb, '{status}', 
              CASE
                 WHEN relation ->> 'status' = 'Notlive' THEN '"No More"'::jsonb
                 ELSE relation -> 'status'
               END) as relation_updated
    from mytable t,
         jsonb_array_elements(t.col->'relations') as relation
   ) as s
   group by col
) as u
where u.col = t.col

Demo here

相关问题