I need to fetch data like the below:
select u.id
from public.user u
where u.reporting_id in (select u.id from public.user u
where u.reporting_id = ?)
is there any best way of doing same in PostgreSQL
I need to fetch data like the below:
select u.id
from public.user u
where u.reporting_id in (select u.id from public.user u
where u.reporting_id = ?)
is there any best way of doing same in PostgreSQL
2
Answers
To query data from a self-referencing table in PostgreSQL, you can use a recursive Common Table Expression (CTE) with the WITH RECURSIVE clause. This allows you to traverse the hierarchical structure of the table.
Here’s an example of how you could query all employees and their hierarchical structure:
This query creates a recursive CTE named EmployeeHierarchy that starts with employees who don’t have a manager (manager_id IS NULL) and then recursively joins with employees who have the same manager, continuing the hierarchy. Adjust the column names based on your actual table structure.
It depends on what you want to achieve.
For listing users 2 levels down from user 9 for example (users who report to users under user 9), your query (aliasing aside) is not only only correct, it’s the best approach, easiest to optimize by the planner.
If you actually want the entire structure under user 9, dynamically, regardless of how many levels deep it runs, you’ll need recursion:
Under the hood, it is not actually recursive – it does the job iteratively, re-evaluating the second
select
and attaching more rows in each round until it reaches a point when it finds nothing or hits a limit.It’s always advised that you add that
limit
clause outside to avoid running out of memory if you do something wrong, as well ascycle
detection if your structure isn’t guarded against loops, where a row can link to itself or a sequence of links can result in a closed loop of relations.Demo at db<>fiddle