Three nested tables exist: user_groups, users, projects. Each user_group has many users and, in turn, each user has many projects.
Each project has an ordinal assigned, 1-5 (step_number).
I would like to provide a summary for each user group. Each user group summary should include the users' projects and their unique progress of the users' projects and the steps they are at. Importantly, I would like to also like to select users projects with projects for a specific ordinal step. In other words, I would like to include the sibling projects for a users' steps.
For example, below, I would like all users aggregated by user_groups.id with projects that are step 3.
+------------+---------------------------------+
| User Group | Summary (Project Name: 1, 2, 5) |
+------------+---------------------------------+
| 1 | proj1: 2, 3, 5; proj2: 3, 5… |
| 2 | proj33: 2, 3; proj 44: 1, 3 |
| 3 | proj55: 2, 3, 4; proj 66: 1, 3 |
+------------+---------------------------------+
The initial instinct was to write a query like this:
SELECT
user_groups.id,
STRING_AGG( DISTINCT(projects.step_number), ', ') AS summary
FROM user_groups
INNER JOIN users ON user_groups.id = users.user_group_id
LEFT JOIN projects ON users.id = projects.user_id
WHERE step_number = 3
GROUP BY user_group.id
However, that only returns projects where the step number is 3 and not the other steps for that user's other project. That makes sense, but how do I include all the sibling projects for that user_id?
I also tried different joins, but I am guessing and clearly unclear on how to solve this problem with SQL.
Here are some simplified table definitions
Table "public.user_groups"
Column | Type | Modifiers
------------+-----------------------------+-------------------------------------------------------
id | integer | not null default nextval('user_groups_id_seq'::regclass)
created_at | timestamp without time zone |
Table "public.users"
Column | Type | Modifiers
---------------+-----------------------------+-------------------------------------------------------
id | integer | not null default nextval('users_id_seq'::regclass)
user_group_id | integer |
gender | character varying(255) |
created_at | timestamp without time zone |
first_name | character varying(255) |
last_name | character varying(255) |
Table "public.projects"
Column | Type | Modifiers
--------------+-----------------------------+-------------------------------------------------------
id | integer | not null default nextval('projects_id_seq'::regclass)
user_id | integer |
step_number | integer |
created_at | timestamp without time zone |
updated_at | timestamp without time zone |
start_dt | date |
end_dt | date |
project_name | text |