Using Postgres 9.4, I am looking for a way to merge two (or more) json
or jsonb
columns in a query. Consider the following table as an example:
id | json1 | json2
----------------------------------------
1 | {'a':'b'} | {'c':'d'}
2 | {'a1':'b2'} | {'f':{'g' : 'h'}}
Is it possible to have the query return the following:
id | json
----------------------------------------
1 | {'a':'b', 'c':'d'}
2 | {'a1':'b2', 'f':{'g' : 'h'}}
Unfortunately, I can't define a function as described here. Is this possible with a "traditional" query?
SELECT jsonb_merge('{"a": 1, "b": 9, "c": 3, "e":5}'::jsonb, '{"b": 2, "d": 4}'::jsonb, '{"c","e"}'::text[]) as jsonb
In Postgres 9.5+ you can merge JSONB like this:
Or, if it's JSON, coerce to JSONB if necessary:
Or:
(Otherwise, any null value in
json1
orjson2
returns an empty row)For example:
Kudos to @MattZukowski for pointing this out in a comment.
FYI, if someone's using jsonb in >= 9.5 and they only care about top-level elements being merged without duplicate keys, then it's as easy as using the || operator:
Also you can tranform json into text, concatenate, replace and convert back to json. Using the same data from Clément you can do:
You could also concatenate all json1 into single json with:
This function would merge nested json objects
Here is the complete list of build-in functions that can be used to create json objects in PostgreSQL. http://www.postgresql.org/docs/9.4/static/functions-json.html
row_to_json
andjson_object
doest not allow you to define your own keys, so it can't be used herejson_build_object
expect you to know by advance how many keys and values our object will have, that's the case in your example, but should not be the case in the real worldjson_object
looks like a good tool to tackle this problem but it forces us to cast our values to text so we can't use this one eitherWell... ok, wo we can't use any classic functions.
Let's take a look at some aggregate functions and hope for the best... http://www.postgresql.org/docs/9.4/static/functions-aggregate.html
json_object_agg
Is the only aggregate function that build objects, that's our only chance to tackle this problem. The trick here is to find the correct way to feed thejson_object_agg
function.Here is my test table and data
And after some trials and errors with
json_object
here is a query you can use to merge json1 and json2 in PostgreSQL 9.4EDIT: for PostgreSQL 9.5+, look at Zubin's answer below