I have a table users
representing a hierarchical tree like this:
Column | Type | Comment |
---|---|---|
user_id | integer | sequence |
user_type | integer | 1 for group of users 2 for normal user |
group_id | integer | Reference to a user in the same table with user_type = 1 |
user_name | varchar(xxx) |
The group_id column references another user_id so that groups and users are stored in the same table.
The master group_id is 0.
Like this:
user_id | user_type | group_id | user_name |
---|---|---|---|
0 | 1 | null | 'All users' |
5 | 2 | 0 | 'USER1' |
6 | 2 | 0 | 'USER2' |
11 | 1 | 0 | 'SUBGROUP1' |
12 | 1 | 11 | 'SUBGROUP2' |
13 | 2 | 12 | 'USER3' |
20 | 1 | 0 | 'SUBGROUP3' |
21 | 2 | 20 | 'USER4' |
Notice that:
- There can be gaps in user_id.
- A group can contain nothing or any number of groups or users.
I have already managed to retrieve the full tree, properly indented and sorted, by using the connect by
oracle statement.
This is not my question here.
My question is:
Given a user_id to a query, how to browse the tree up to the master group 'All Users' and output as a result the full path from the leaf to the master group ?
Example 1: I run the query for USER1, i want the following output:
All Users
- USER1
Example 2: I run the same query for USER3, i want the following output:
All Users
- SUBGROUP1
-- SUBGROUP2
--- USER3
I hope someone could help me on this.
For information i post the query to retrieve the full tree, for you to see the use of connect by
and start with
.
I'm sure this query is close to the one i want, but my tries never produce the result i want.
select
lpad('-', (level - 1) * 2, ' ') || u.user_name as padded_name,
u.userid,
u.user_group,
u.user_type,
level
from users u
connect by prior u.user_id = u.group_id
start with u.user_id = 0
order siblings by upper(u.user_name);