1

for example I have a table:

CREATE TABLE fruit(id bigint, data jsonb);

and a row for example is:

1,    
{
   "type": "pinapple",
   "store1": {
   "first_added": "<some timestamp>",
   "price": "10",
   "store_id": "1",
   "comments": "some comments..."
},
   "store2": {
   "first_added": "<some timestamp>",
   "price": "11",
   "store_id": "2",
   "comments": "some comments..."
},
   .... more stores
}

In case of update I have the fruit id and store data :

1,
"store1": {
            "price": "12",
            "store_id": "1",
            "comments": "some comments...V2"
        }

I want to update entire store object in fruit entry (for store1), except the first_added field.

Any idea how I can accomplish it via JSONB operators or functions?

Thanks

0

2 Answers 2

2

You can use

UPDATE fruit
SET data = data || jsonb_set($1::jsonb, '{store1,first_added}', data#>'{store1,first_added}')
WHERE id = 1;

(online demo)
where the parameter $1 is set to the value {"store1": {"price": "12", "store_id": "1", "comments": "some comments...V2"}}.

Or if you need the key to be dynamic, use

UPDATE fruit
SET data = jsonb_set(data, ARRAY[$2::text], jsonb_set($1::jsonb, '{first_added}', data->$2->'first_added'))
WHERE id = 1;

(online demo)

Sign up to request clarification or add additional context in comments.

2 Comments

looks great, but with store1 is dynamically changed? i.e., how it can be $2?
look great, thanks mate!, this is the query: (same as in the dbfiddle, which is a great tool) UPDATE fruit SET data = jsonb_set(data, ARRAY[key], jsonb_set(json_value, '{first_added}', data->key->'first_added')) FROM (VALUES('store1', '{"price": "12", "store_id": "1", "comments": "some comments...V2"}'::jsonb)) AS vals(key, json_value) WHERE id = 1;
0

You can use the jsonb_set function to change the desired element, then use the jsonb_build_object function to create a new dataset, then concatenate the data with the || operator to keep the rest of the data(first_added,...)

update table1 
  set data = jsonb_set(data, '{store1}',  jsonb_build_object('first_added', data->'store1'->'first_added', 'price', 12, 'store_id', 1, 'comments', 'some comments...V2'))
where id  = 1; 

Demo in DBfiddle

4 Comments

thanks, but I don't want to be depends in the store fields? i.e. those fields can be changed (added or removed), override all fields expects the first_added field
@ShayZambrovski But you are not dependent on store fields. If you add your fields to jsonb_build_object, they will also be added as new ones. Just if you specify those fields that are already in the store, then they are updated
@ShayZambrovski I understand you, you want to be able to change all the data of the store, but keep the first_added field, if so, then see my modified answer)
But still, I need to "know" all the fields, I want to avoid it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.