Как сделать этот sql с запросом array_agg?

Я хочу сделать запрос

select * from projects where user_id = 3;

и в зависимости от его результата rМне нужно сделать n запросы, где n это длина l из r, например:

| id | project_name | description | user_id |
| 1  | Project A    | lorem ipsu  | 3       |
| 4  | Project B    | lorem ipsu  | 3       |

l => 2 тогда:

select * from images where project_id = 1;
select * from images where project_id = 4;

Хорошо, вы можете увидеть, где это происходит, если l слишком большой Слишком много вариантов выбора, слишком много доступа к базе данных. Есть ли лучший способ достичь конечного результата, например, так:

| id | project_name | description | user_id | images           |
| 1  | Project A    | lorem ipsu  | 3       | {imgX,imgY,imgZ} |
| 4  | Project B    | lorem ipsu  | 3       | {imgA,imgB}      |

Я слышал о array_agg функция на postgres. Может быть, это ответ? В любом случае, это мои описания таблиц:

                             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 | 

И заранее спасибо:D

3 ответа

Решение

array_agg похож на любую другую агрегатную функцию (count, sum), но возвращает скалярное значение вместо массива. То, что вам нужно, может быть достигнуто простым объединением и группированием двух таблиц.

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

Вы хотите записи из projects плюс записи в image names as array соответствие по 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'

http://sqlfiddle.com/

Вероятно, самое простое решение для вас - это дополнительный выбор. Это ближе всего подходит к человеку SELECT заявления, которые вы упоминаете ранее:

SELECT * FROM images
WHERE project_id IN (
  SELECT project_id FROM projects
  WHERE user_id = 3);
Другие вопросы по тегам