4

I'm getting grips with the JSONB functionality in Postgres >= 9.5 (and loving it) but have hit a stumbling block. I've read about the ability to concatenate JSON fields, so '{"a":1}' || '{"b":2}' creates {"a":1,"b":2}, but I'd like to do this across the same field in multiple rows. e.g.:

select row_concat_??(data) from table where field = 'value'

I've discovered the jsonb_object_agg function which sounds like it would be what I want, except that the docs show it taking multiple arguments, and I only have one.

Any ideas how I would do this? jsonb_agg creates an array successfully so it feels like I'm really close.

2 Answers 2

9

After some digging around with custom aggregates in Postgres, I have the following:

DROP AGGREGATE IF EXISTS jsonb_merge(jsonb);

CREATE AGGREGATE jsonb_merge(jsonb) (
    SFUNC = jsonb_concat(jsonb, jsonb),
    STYPE = jsonb,
    INITCOND = '{}'
)

Which is then usable as:

SELECT group_id, jsonb_merge(data) FROM table GROUP BY group_id
Sign up to request clarification or add additional context in comments.

2 Comments

You do not need to create the function, use jsonb_concat(jsonb, jsonb).
Oh wow, you're right. So much easier. Edited to reflect that, thanks @klin!
2

Use jsonb_each():

with data(js) as (
    values
    ('{"a": 1}'::jsonb),
    ('{"b": 2}')
)
select jsonb_object_agg(key, value)
from data
cross join lateral jsonb_each(js);

 jsonb_object_agg 
------------------
 {"a": 1, "b": 2}
(1 row) 

Comments

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.