You have to first flatten the JSON field of your table and then re-aggregate into the desired structure. Well, not very simple indeed.
-- Sample data
create table t (id integer, root jsonb);
insert into t values
(1, '[{"field_1": "ex_1", "field_2": "ex_2"}, {"field_1": "ex_3", "field_2": "ex_4"}]'),
(2, '[{"field_11": "ex_11", "field_12": "ex_12"}, {"field_11": "ex_13", "field_12": "ex_14"}]'),
(3, '[{"field_21": "ex_21", "field_22": "ex_22"}, {"field_21": "ex_23", "field_22": "ex_24"}]');
-- Flatten (example)
select id, k, v from t
cross join lateral jsonb_array_elements(root) j
cross join lateral jsonb_each(j) je(k, v);
-- Flatten and re-aggregate
with cte as
(
select id, k, json_agg(v) newroot
from t
cross join lateral jsonb_array_elements(root) j
cross join lateral jsonb_each(j) je(k, v)
group by id, k order by id, k
)
select id, jsonb_object_agg(k, newroot) newroot
from cte group by id;
id |
newroot |
1 |
{"field_1": ["ex_1", "ex_3"], "field_2": ["ex_2", "ex_4"]} |
2 |
{"field_11": ["ex_11", "ex_13"], "field_12": ["ex_12", "ex_14"]} |
3 |
{"field_21": ["ex_21", "ex_23"], "field_22": ["ex_22", "ex_24"]} |
DB-fiddle
Alternatively, using a scalar subquery (and maybe more efficient):
select id,
(
select jsonb_object_agg(k, v)
from (
select k, jsonb_agg(v) v
from jsonb_array_elements(root) j, lateral jsonb_each(j) je(k, v)
group by k
) jarr
) new_root
from t;