Update certain array elements of a json array in PostgreSQL 9.4

后端 未结 2 1572
野趣味
野趣味 2021-01-18 04:25

I have a table like this;

CREATE TABLE test (
  id BIGSERIAL PRIMARY KEY,
  data JSONB
);

INSERT INTO test(data) VALUES(\'[1,2,\"a\",4,\"8\",6]\'); -- id =          


        
相关标签:
2条回答
  • 2021-01-18 05:11

    You cannot manipulate selected elements of a json / jsonb type directly. Functionality for that is still missing in Postgres 9.4 (see @Craig's comment). You have to do 3 steps:

    1. Unnest / decompose the JSON value.
    2. Manipulate selected elements.
    3. 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>') in pg 9.4:

    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
    0 讨论(0)
  • 2021-01-18 05:14

    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]
    
    0 讨论(0)
提交回复
热议问题