Alastair
Alastair

Reputation: 6114

Postgres: concatenate JSONB values across rows?

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.

Upvotes: 4

Views: 1755

Answers (2)

Alastair
Alastair

Reputation: 6114

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

Upvotes: 9

klin
klin

Reputation: 121604

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) 

Upvotes: 2

Related Questions