Search code examples
sqljsonpostgresqljsonb

Update jsonb column with value from row_to_json()


I have a table containing a data that look like:

col1       col2     col3     col4      json_data  
----------------------------------------------------
 a           b        c       d       {"mock":"abc123"}
 e           f        g       h       {"mock":"def456"}

The column json_data is a column with jsonb type that contains some json that do not relate to anything which I want to update with row_to_json() function. The result should be something like this

col1       col2     col3     col4      json_data  
----------------------------------------------------
 a           b        c       d       {"col1:"a", "col2:"b","col3:"c","col4:"d"}
 e           f        g       h       {"col1:"e", "col2:"f","col3:"g","col4:"h"}

which will get the result from row_to_json function to update each row. I am not sure how can I use the UPDATE query to do this.


Solution

  • Use the function to_jsonb() and the - operator to remove the column json_data from the resulting json object:

    create table my_table(col1 text, col2 text, col3 text, col4 text, json_data jsonb);
    insert into my_table values
    ('a', 'b', 'c', 'd', '{"mock":"abc123"}'),
    ('e', 'f', 'g', 'h', '{"mock":"def456"}');
    
    update my_table t
    set json_data = to_jsonb(t)- 'json_data'
    returning *;
    
     col1 | col2 | col3 | col4 |                      json_data                       
    ------+------+------+------+------------------------------------------------------
     a    | b    | c    | d    | {"col1": "a", "col2": "b", "col3": "c", "col4": "d"}
     e    | f    | g    | h    | {"col1": "e", "col2": "f", "col3": "g", "col4": "h"}
    (2 rows)    
    

    You can remove more than one column, e.g.:

    update my_table t
    set json_data = to_jsonb(t)- 'json_data'- 'col3'- 'col4'
    returning *;
    
     col1 | col2 | col3 | col4 |         json_data          
    ------+------+------+------+----------------------------
     a    | b    | c    | d    | {"col1": "a", "col2": "b"}
     e    | f    | g    | h    | {"col1": "e", "col2": "f"}
    (2 rows)    
    

    Alternatively, you can use jsonb_build_object() instead of to_jsonb():

    update my_table t
    set json_data = jsonb_build_object('col1', col1, 'col2', col2)
    returning *;
    
     col1 | col2 | col3 | col4 |         json_data          
    ------+------+------+------+----------------------------
     a    | b    | c    | d    | {"col1": "a", "col2": "b"}
     e    | f    | g    | h    | {"col1": "e", "col2": "f"}
    (2 rows)