如何使用PostgreSQL更新JSONB数组上的多个值

问题描述

今天我正在尝试根据id键更新jsonb数组的多个值。

我在“人”表中具有列uniqueid和jsarray。

例如从人中选择*

1,[{"id": 1101,"val": "testing1","valuom": "","description": "Desc_test_1"},{"id": 1105,"val": "testing2","description": "Desc_test_2"},{"i d": 1108,"description": "Desc_test_3"}]

我需要根据id键更新Description,val和valuom的值。

例如,更新jsarray列,其中id = 1101和uniqueid = 1; 需要o / p作为:

  1,[{"id":1101,"val":"testing5","valuom":"test5","description":"Desc_test_5"},{"id":1105,"val":"testing2","valuom":"","description":"Desc_test_2"},{"id":1108,"description":"Desc_test_3"}];

解决方法

您可以使用其中包含jsonb_set()函数的查询:

WITH p AS
(
 SELECT ('{'||idx-1||',val}')::text[] AS path_val,('{'||idx-1||',desc}')::text[] AS path_desc
   FROM people 
  CROSS JOIN jsonb_array_elements(jsarray) 
   WITH ORDINALITY arr(j,idx)
  WHERE (j->>'id')::int=1101 
    AND uniqueid = 1
)
UPDATE people
   SET jsarray = jsonb_set(
                           jsonb_set(jsarray,p.path_val,'"testing5"',false),p.path_desc,'"Desc_test_5"',false
                 )
  FROM p

然后

WITH p AS
(
 SELECT ('{'||idx-1||',desc}')::text[] AS path_desc,valuom}')::text[] AS path_valuom
   FROM people 
  CROSS JOIN jsonb_array_elements(jsarray) 
   WITH ORDINALITY arr(j,idx)
  WHERE (j->>'id')::int=1105 
    AND uniqueid = 1
)
UPDATE people
   SET jsarray = jsonb_set(
                       jsonb_set(
                                jsonb_set(jsarray,'"testing21"','"Desc_test_21"',p.path_valuom,'"test21"',false
                 )
  FROM p

连续JSONB值内的每个相关ID值。

Demo