I need to update id=2
when id=46
- probably using CASE
expression as I have multiple objects with different values.
select q.a from (select json_array_elements_text('[{"id":46,"value":"a"},{"id":35,"value":"b"}]'::json) as a)q.
Also, why do I get the error "operator does not exist: text ->> unknown" when trying to run:
select q.a from (select json_array_elements_text('[{"id":46,"value":"a"}]'::json) as a)q where a->>'id'=46
Just want to understand what I am missing.
CodePudding user response:
For Postgres 12 or later, and jsonb
(not json
):
UPDATE tbl
SET a = (
SELECT jsonb_agg(CASE WHEN obj->>'id' = '46'
THEN jsonb_set(obj, '{id}', '2', false)
ELSE obj END)
FROM jsonb_array_elements(a) obj
)
WHERE a @? '$.id ? (@ == 46)';
See:
why do I get the error "operator does not exist: text ->> unknown" ...
As the name of the function json_array_elements_text()
hints, it returns type text
. Use json_array_elements()
instead for your purpose. See:
Also, a ->> 'id'
returns text
, so you can't compare it to an integer
. This works:
SELECT q.a
FROM json_array_elements('[{"id":46,"value":"a"}]'::json) AS q(a)
WHERE a ->> 'id' = '46';