1

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

3 Answers 3

2

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
Sign up to request clarification or add additional context in comments.

1 Comment

Sorry, I thought it was easy to understand. Edited.
1

You want records from projects plus records in image names as array matching by project_id :

SELECT *
FROM   projects
LEFT JOIN LATERAL (SELECT array_agg(name) AS images FROM images WHERE project_id = projects.project_id) x ON true
WHERE user_id = '3'

sqlfiddle

Comments

0

Probably the easiest solution for you is a sub-select. This comes closest to the individual SELECT statements that you mention earlier:

SELECT * FROM images
WHERE project_id IN (
  SELECT project_id FROM projects
  WHERE user_id = 3);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.