I want to make a query
select * from projects where user_id = 3;
and depending on it's result r
, I need to make n
queries, where n
is the length l
of r
. eg:
| id | project_name | description | user_id |
| 1 | Project A | lorem ipsu | 3 |
| 4 | Project B | lorem ipsu | 3 |
l => 2
then:
select * from images where project_id = 1;
select * from images where project_id = 4;
Ok, you can see where this is going if l
is too big. Too many selects, too many access to the database. Is there a better way to achieve an end result like so:
| id | project_name | description | user_id | images |
| 1 | Project A | lorem ipsu | 3 | {imgX,imgY,imgZ} |
| 4 | Project B | lorem ipsu | 3 | {imgA,imgB} |
I heard about array_agg
function on postgres. Maybe that's the answer? Anyways, these are my table descriptions:
Table "public.projects"
Column | Type | Modifiers
-------------+--------------------------+-------------------------------------------------------
id | integer | not null default nextval('projects_id_seq'::regclass)
name | character varying(255) |
description | character varying(255) |
user_id | integer |
created_at | timestamp with time zone |
updated_at | timestamp with time zone |
Table "public.images"
Column | Type | Modifiers
------------+--------------------------+-----------------------------------------------------
id | integer | not null default nextval('images_id_seq'::regclass)
name | character varying(255) |
url | character varying(255) |
project_id | integer |
created_at | timestamp with time zone |
updated_at | timestamp with time zone |
And thank you in advance :D
array_agg
is like any other aggregate function (count, sum), but returns an array instead of a scalar value. What you need can be achieved simply by joining and grouping the 2 tables.
SELECT p.id, p.name, p.description, p.user_id, array_agg(i.name) images
FROM projects p
LEFT JOIN images i ON p.id = i.project_id
GROUP BY p.id, p.name, p.description, p.user_id