I have below tables
CREATE TABLE employee(id serial PRIMARY KEY,employee jsonb); CREATE TABLE perks_details(id serial PRIMARY KEY,details jsonb); insert into employee(employee) values ('{"name": "name1", "perks": [ {"id": 123, "valid_from": "T23:28:56.782Z"}, {"id": 456, "valid_from": "T23:28:56.782Z"}, {"id": 789, "valid_from": "T23:28:56.782Z"} ] }'); insert into perks_details(details) values('{"id":123,"detail1":"lorem","detail2":"lorem"}'); insert into perks_details(details) values('{"id":123,"detail3":"lorem","detail4":"lorem"}'); insert into perks_details(details) values('{"id":456,"detail5":"lorem","detail6":"lorem"}');
How to write select query from employee
left join perks_details
on perks id with id in perks_details table and aggregate functions so my result data looks like:
{ "name": "name1", "perks": [ { "id": 123, "valid_from": "T23:28:56.782Z", "details": [ { "id": 123, "detail1": "lorem", "detail2": "lorem" }, { "id": 123, "detail3": "lorem", "detail4": "lorem" } ] }, { "id": 456, "valid_from": "T23:28:56.782Z", "details": [ { "id": 456, "detail5": "lorem", "detail6": "lorem" } ] }, { "id": 789, "valid_from": "T23:28:56.782Z", "details": [] } ] }
I tried multiple variations and couldn’t get near to a working query. Please advise/assist me here.
UPDATE I have this query with left join but the results are not what I expected
select e.id, perk, perks_details.details from employee AS e, jsonb_array_elements(employee->'perks') perk LEFT JOIN perks_details on perks_details.details -> 'id' = perk->'id' group by e.id, perk.value, perks_details.details;
Advertisement
Answer
Hi you can do it in this way:
with cte as ( select t1.employee->>'name' "name", t2.id, t2.valid_from, json_agg(t3.details) "details" from employee t1 cross join lateral jsonb_to_recordset(employee->'perks') as t2(id int,valid_from time) left join perks_details t3 on t2.id::text=t3.details->>'id' group by 1,2,3 ) select row_to_json(t) from ( select name, json_agg(jsonb_build_object('id',id,'valid_from',valid_from,'details',details)) "perks" from cte group by name ) t