Update certain array elements of a json array in PostgreSQL 9.4
You can do this from PostgreSQL 9.5 with jsonb_set:
INSERT INTO test(data) VALUES('[1,2,"a",4,"8",6]');
UPDATE test SET data = jsonb_set(data, '{2}','"b"', false) WHERE id = 1
Try it out with a simple select:
SELECT jsonb_set('[1,2,"a",4,"8",6]', '{2}','"b"', false)
-- [1, 2, "b", 4, "8", 6]
And if you want to update two fields you can do:
SELECT jsonb_set(jsonb_set('[1,2,"a",4,"8",6]', '{0}','100', false), '{2}','"b"', false)
-- [100, 2, "b", 4, "8", 6]
For Postgres 9.5 or later use jsonb_set()
. See later answer of adriaan.
You cannot manipulate selected elements of a json
/ jsonb
type directly. Functionality for that is still missing in Postgres 9.4. You have to do 3 steps:
- Unnest / decompose the JSON value.
- Manipulate selected elements.
- Aggregate / compose the value back again.
To replace the 3rd element of the json array (data->3
) in the row with id = 1
with a given (new) value ('<new_value>'
):
UPDATE test t
SET data = t2.data
FROM (
SELECT id, array_to_json(
array_agg(CASE WHEN rn = 1 THEN '<new_value>' ELSE elem END))
) AS data
FROM test t2
, json_array_elements_text(t2.data) WITH ORDINALITY x(elem, rn)
WHERE id = 1
GROUP BY 1
) t2
WHERE t.id = t2.id
AND t.data <> t2.data; -- avoid empty updates
About json_array_elements_text()
:
- How to turn JSON array into Postgres array?
About WITH ORDINALITY
:
- PostgreSQL unnest() with element number