I have a table as shown below -
ID | NAME | PARENT
1 | Global | null
2 | USA | 1
3 | Canada | 1
4 | USA-1 | 2
5 | USA-11 | 4
The column parent refers to the column id i.e., Global is the root. For USA-11, USA-1 is the parent, USA is the grandparent and Global is the great grand parent. It is a rugged hierarchy and can go upto any level. I need help in writing a query that will expand this hierarchy in the following manner -
ID | NAME | PARENT | Distance_from_parent
1 | Global | Global | 0
2 | USA | USA | 0
2 | USA | Global | 1
3 | Canada | Canada | 0
3 | Canada | Global | 1
4 | USA-1 | USA-1 | 0
4 | USA-1 | USA | 1
4 | USA-1 | Global | 2
5 | USA-11 | USA-11 | 0
5 | USA-11 | USA-1 | 1
5 | USA-11 | USA | 2
5 | USA-11 | Global | 3
So if you notice, I'm repeating every location name against itself and its hierarchy. The column "distance_from_parent" is the distance from the parent mentioned in the "Parent" column.
I have tried this using Connect By, Level and prior, but unable to achieve this kind of output.
The DDL for this is -
create table subsidiary (id number, name varchar2(50), parent number);
insert into subsidiary (id, name, parent) values (1, 'Parent', null);
insert into subsidiary (id, name, parent) values (2, 'USA', 1);
insert into subsidiary (id, name, parent) values (3, 'Canada', 1);
insert into subsidiary (id, name, parent) values (4, 'USA-1', 2);
insert into subsidiary (id, name, parent) values (5, 'USA-11', 4);
Use a hierarchical query with CONNECT_BY_ROOT
:
SELECT CONNECT_BY_ROOT( ID ) AS id,
CONNECT_BY_ROOT( name ) AS name,
name AS parent,
LEVEL - 1 AS distance_from_parent
FROM subsidiary
CONNECT BY PRIOR parent = id
ORDER BY id, distance_from_parent;
So for your test data:
CREATE TABLE subsidiary ( ID, NAME, PARENT ) AS
SELECT 1, 'Global', null FROM DUAL UNION ALL
SELECT 2, 'USA', 1 FROM DUAL UNION ALL
SELECT 3, 'Canada', 1 FROM DUAL UNION ALL
SELECT 4, 'USA-1', 2 FROM DUAL UNION ALL
SELECT 5, 'USA-11', 4 FROM DUAL;
This outputs:
ID | NAME | PARENT | DISTANCE_FROM_PARENT -: | :----- | :----- | -------------------: 1 | Global | Global | 0 2 | USA | USA | 0 2 | USA | Global | 1 3 | Canada | Canada | 0 3 | Canada | Global | 1 4 | USA-1 | USA-1 | 0 4 | USA-1 | USA | 1 4 | USA-1 | Global | 2 5 | USA-11 | USA-11 | 0 5 | USA-11 | USA-1 | 1 5 | USA-11 | USA | 2 5 | USA-11 | Global | 3
db<>fiddle here