Reputation: 81
I have following tables
Table 1: person
columns: id,name,address,code
Table 2: carDetails
columns: id,person_id,car_brand
constraints: FL==>carDetails(person_id) reference person(id)
Note: carDetails is having multiple details for single person
Table 3: mobileDetails
columns: id,person_id,mobile_brand
constraints: FL==>mobileDetails(person_id) reference person(id)
Note: mobileDetails is having multiple details for single person
Similarly i have lot of details like car and mobile for person
What I want to select is:
person(id),
person(name),
Array of carDetails(brand) belonging to that particular person(id)
Array of mobileDetails(brand) belonging to that particular person(id)
Upvotes: 0
Views: 47
Reputation: 1269503
You should write this query using subqueries for the aggregation:
select p.*, c.car_brands, m.mobile_brands
from person p left join
(select c.person_id, array_agg(cd.car_brand) as car_brands
from car_details c
group by c.person_id
) c
on c.person_id = p.id left join
(select m.person_id, array_agg(m.mobile_brand) as mobile_brands
from mobile_details m
group by m.person_id
) m
on m.person_id = m.id;
Two notes:
left join
, in case you have no data in one of the tables for some people.distinct
to array_agg()
that incurs a performance penalty.If you are filtering the people, it is often more efficient to do this using a subquery or (equivalently) as lateral join:
select p.*,
(select array_agg(cd.car_brand) as car_brands
from car_details c
where c.person_id = p.id
) as car_brands,
(select array_agg(m.mobile_brand) as mobile_brands
from mobile_details m
where m.person_id = p.id
) as mobile_brands
from person p;
Upvotes: 1