Suppose the following,
create table product(id serial primary key);
create table product_image(id serial primary key, product_id bigint references product(id));
create table chat(id serial primary key, product_id bigint references product(id));
insert into product values(1), (2), (3);
insert into product_image values(30, 1), (31, 1);
insert into chat values(50, 1), (51, 2);
I’m expecting the following result:
chat_id | product |
---------+------------------------------------------+
50 | {"id":1,"images":[{"id":30},{"id":31}]} |
51 | {"id":2,"images":[]} |
Here’s what I’ve tried,
select
c.id as chat_id,
json_build_object(
'id', p.id,
'images', to_jsonb(
select * from product_image pi
join product p on p.id = pi.product_id
)
) as product
from chat c
join product p on p.id = c.product_id
join product_image pi on pi.product_id = p.id
I feel like I’m close, but I keep catching unexpected results.
What am I doing wrong here?
2
Answers
Your subquery is not joined to your outer query. The imo easiest and most straightforward way to achieve this is using only subqueries, using
WHERE
conditions to select only those rows that match the outer object:(online demo)
Instead of the
ARRAY(…)
subquery syntax, you can also usejsonb_agg
(demo), but it returnsnull
instead of an empty array when there are no elements.You can do it using
json_build_object
andjson_agg
as follows :Demo here