sql nested query - group results by parent
I have the need to return tree like results from a single table. At the moment im using connect by and start with to ensure that all the correct results are returned.
select id,parent_id
from myTable
connect by prior id = parent_id start with name = 'manager'
group by id, parent_id开发者_C百科
order by parent_id asc
However i want the results to return in tree structure. So each time a parent row is found its children rows will be displayed directly underneath it. Then move onto next parent and do the same
Expected results
- Parent A
- child a
- child b
- Parent B
- child c
- child d
Actual results
- Parent A
- Parent B
- child a
- child b
- child c
- child d
Is it possible to do this in oracle? My table uses a parent_id field to identify when a row has a parent. Every row also has a sort order, which is the order it should be sorted under its parent and a unique Id.
I'm using an Oracle DB
What you want is to use ORDER SIBLINGS BY
. The query you have is ordering by the parent_id
column which is overriding any hierarchical ordering.
The query below should do what you need it to do:
with my_hierarchy_data as (
select 1 as id, null as parent_id, 'Manager' as name from dual union all
select 2 as id, 1 as parent_id, 'parent 1' as name from dual union all
select 3 as id, 1 as parent_id, 'parent 2' as name from dual union all
select 4 as id, 2 as parent_id, 'child 1' as name from dual union all
select 5 as id, 2 as parent_id, 'child 2' as name from dual union all
select 6 as id, 3 as parent_id, 'child 3' as name from dual union all
select 7 as id, 3 as parent_id, 'child 4' as name from dual
)
select id, parent_id, lpad('- ', level * 2, ' ') || name as name
from my_hierarchy_data
connect by prior id = parent_id
start with name= 'Manager'
order siblings by parent_id asc
There is a special value level
that can be used in Oracle hierarchical queries. It returns 1 for rows at the top level of the hierarchy, 2 for their children, and so on. You can use this to create indentation like this:
select lpad('- ',level*2,' ') || name
from myTable
connect by prior id = parent_id start with name = 'manager'
group by id, parent_id
精彩评论