I have a table of profiles
that have data related to the managers of a user.
There can multiple levels of managers for a user.
I need to write a query to get all the managers of a user.
Official manager_id
is stored in column text
= A
.
Table Name profiles
id | text | manager_id | user_id |
---|---|---|---|
1 | A | 20 | 50 |
2 | B | 20 | 50 |
3 | A | 21 | 20 |
4 | B | NULL | 20 |
5 | C | NULL | 20 |
6 | A | 22 | 21 |
7 | B | NULL | 21 |
9 | A | NULL | 22 |
For example,
If user_id=50
then,
50
manager's is 20
20
manager's is 21
21
manager's is 22
21
manager's is NULL
So, the output should be 20,21,22
Similarly, if user_id=20
the output should be 21,22
I tried a couple of queries but it doesn't return the expected output.
CodePudding user response:
The recursive query you're looking for should feature:
- base step, which begins with distinct couples of user_id and manager_id from the input table
- recursive step, which self joins the table with the current recursive result, matching manager of the second to be users of the first
Once you get all matches, you can aggregate your values by "user_id" with ARRAY_AGG
.
WITH RECURSIVE cte AS (
SELECT DISTINCT user_id, manager_id
FROM tab
WHERE manager_id IS NOT NULL
UNION ALL
SELECT usr.user_id,
mgr.manager_id
FROM cte usr
INNER JOIN tab mgr
ON usr.manager_id = mgr.user_id
WHERE mgr.manager_id IS NOT NULL
)
SELECT user_id,
ARRAY_AGG(manager_id) AS managers
FROM cte
GROUP BY user_id
Check the demo here.