patternsqlMinor
Update all values for given key nested in JSON array of objects
Viewed 0 times
updateobjectsallarrayjsonnestedforvaluesgivenkey
Problem
I have a
I want to update the
The above query added a new object within the array like the following:
I want the output like:
I also tried
If this can be solved with custom functions, also fine.
jsonb column data in a Postgres table my_table. It contains the following data:[
{"id":"1","status":"test status1","updatedAt":"1571145003"},
{"id":"2","status":"test status2","updatedAt":"1571145323"}
]I want to update the
updatedAt key of all objects in that array using one query. I tried:update my_table set data = data || '{"updatedAt": "1571150000"}';The above query added a new object within the array like the following:
[
{"id":"1","status":"test status1","updatedAt":"1571145003"},
{"id":"2","status":"test status2","updatedAt":"1571145323"},
{"updatedAt":"1571150000"}
]I want the output like:
[
{"id":"1","status":"test status1","updatedAt":"1571150000"},
{"id":"2","status":"test status2","updatedAt":"1571150000"}
]I also tried
jsonb_set(), but that needs the second parameter to be the array index. I can't be sure of the count of JSON objects in the array. If this can be solved with custom functions, also fine.
Solution
First cte unnest all elements of the array, second one update each element and then simply update the original table building the array again.
id | data
-: | :-----------------------------------------------------------------------------------------------------------------------------------
1 | [{"id": "1", "status": "test status1", "updatedAt": "1571150000"}, {"id": "2", "status": "test status2", "updatedAt": "1571150000"}]
db<>fiddle here
with ct as
(
select id, jsonb_array_elements(data) dt
from t
)
, ct2 as
(
select id, jsonb_set(dt, '{updatedAt}', '"1571150000"', false) dt2
from ct
)
update t
set data = (select jsonb_agg(dt2) from ct2 where ct2.id = t.id);select * from t;id | data
-: | :-----------------------------------------------------------------------------------------------------------------------------------
1 | [{"id": "1", "status": "test status1", "updatedAt": "1571150000"}, {"id": "2", "status": "test status2", "updatedAt": "1571150000"}]
db<>fiddle here
Code Snippets
with ct as
(
select id, jsonb_array_elements(data) dt
from t
)
, ct2 as
(
select id, jsonb_set(dt, '{updatedAt}', '"1571150000"', false) dt2
from ct
)
update t
set data = (select jsonb_agg(dt2) from ct2 where ct2.id = t.id);select * from t;Context
StackExchange Database Administrators Q#251133, answer score: 6
Revisions (0)
No revisions yet.