CREATE TABLE table_connect_by ( id1 NUMBER(2,0) , parent_id1 NUMBER(2,0) , code VARCHAR(50) , CONSTRAINT pk_table_connect_by PRIMARY KEY (id1) , CONSTRAINT fk_table_connect_by FOREIGN KEY (parent_id1) REFERENCES table_connect_by (id1) );The sample data creates two hierarchical trees: one starting with node 11 (A_11) and another with node 21 (B_21). The hierarchy depth varies, with some branches extending to level 4:
INSERT INTO table_connect_by (id1, parent_id1, code) VALUES (11, null, 'A_11'); INSERT INTO table_connect_by (id1, parent_id1, code) VALUES (12, 11, 'A_11_12'); INSERT INTO table_connect_by (id1, parent_id1, code) VALUES (13, 11, 'A_11_13'); INSERT INTO table_connect_by (id1, parent_id1, code) VALUES (14, 12, 'A_11_12_14'); INSERT INTO table_connect_by (id1, parent_id1, code) VALUES (15, 12, 'A_11_12_15'); INSERT INTO table_connect_by (id1, parent_id1, code) VALUES (16, 14, 'A_11_12_14_16'); INSERT INTO table_connect_by (id1, parent_id1, code) VALUES (17, 14, 'A_11_12_14_17'); INSERT INTO table_connect_by (id1, parent_id1, code) VALUES (21, null, 'B_21'); INSERT INTO table_connect_by (id1, parent_id1, code) VALUES (22, 21, 'B_21_22'); INSERT INTO table_connect_by (id1, parent_id1, code) VALUES (23, 21, 'B_21_23'); COMMIT;Hierarchical Structure of table_connect_by:
11 (A_11) [ROOT] ├── 12 (A_11_12) │ ├── 14 (A_11_12_14) │ │ ├── 16 (A_11_12_14_16) │ │ └── 17 (A_11_12_14_17) │ └── 15 (A_11_12_15) └── 13 (A_11_13) 21 (B_21) [ROOT] ├── 22 (B_21_22) └── 23 (B_21_23) Legend: - Numbers represent the id1 values - Text in parentheses shows the code values - [ROOT] indicates top-level nodes (parent_id1 = NULL)
SELECT CONNECT_BY_ROOT -- specifies the column that will be the parent t1.id1 AS root_parent_id -- the main parent , t1.id1 AS child_id -- children of the main parent , NVL(t1.parent_id1, 0) AS parent_id1 -- direct parent of the selected child , t1.code AS code , LEVEL AS level_parent_child -- distance between the main parent and selected child FROM table_connect_by t1 CONNECT BY PRIOR t1.id1 = t1.parent_id1;The LEVEL pseudocolumn indicates the depth in the hierarchy, starting from 1 for root nodes. To organize the results in a meaningful order, wrap the query in a subquery and apply ORDER BY:
SELECT * FROM ( SELECT CONNECT_BY_ROOT -- specifies the column that will be the parent t1.id1 AS root_parent_id -- the main parent , t1.id1 AS child_id -- children of the main parent , NVL(t1.parent_id1, 0) AS parent_id1 -- direct parent of the selected child , t1.code AS code , LEVEL AS level_parent_child -- distance between the main parent and selected child FROM table_connect_by t1 CONNECT BY PRIOR t1.id1 = t1.parent_id1 ) ORDER BY root_parent_id, parent_id1, child_id;Query result:
11 11 0 A_11 1 11 12 11 A_11_12 2 11 13 11 A_11_13 2 11 14 12 A_11_12_14 3 11 15 12 A_11_12_15 3 11 16 14 A_11_12_14_16 4 11 17 14 A_11_12_14_17 4 12 12 11 A_11_12 1 12 14 12 A_11_12_14 2 12 15 12 A_11_12_15 2 12 16 14 A_11_12_14_16 3 12 17 14 A_11_12_14_17 3 13 13 11 A_11_13 1 14 14 12 A_11_12_14 1 14 16 14 A_11_12_14_16 2 14 17 14 A_11_12_14_17 2 15 15 12 A_11_12_15 1 16 16 14 A_11_12_14_16 1 17 17 14 A_11_12_14_17 1 21 21 0 B_21 1 21 22 21 B_21_22 2 21 23 21 B_21_23 2 22 22 21 B_21_22 1 23 23 21 B_21_23 2
SELECT CONNECT_BY_ROOT -- specifies the column that will be the parent t1.id1 AS root_parent_id -- the main parent , t1.id1 AS child_id -- children of the main parent , NVL(t1.parent_id1, 0) AS parent_id1 -- direct parent of the selected child , t1.code AS code , LEVEL AS level_parent_child -- distance between the main parent and selected child FROM table_connect_by t1 START WITH t1.id1 = 12 -- specify a main parent to start the selection of sub-children CONNECT BY PRIOR t1.id1 = t1.parent_id1;Query result:
12 12 11 A_11_12 1 12 14 12 A_11_12_14 2 12 15 12 A_11_12_15 2 12 16 14 A_11_12_14_16 3 12 17 14 A_11_12_14_17 3
SELECT CONNECT_BY_ROOT -- specifies the column that will be the parent t1.id1 AS root_parent_id -- the main parent , t1.id1 AS child_id -- children of the main parent , NVL(t1.parent_id1, 0) AS parent_id1 -- direct parent of the selected child , t1.code AS code , LEVEL AS level_parent_child -- distance between the main parent and selected child , SYS_CONNECT_BY_PATH(t1.parent_id1, '/') AS path_parent , SYS_CONNECT_BY_PATH(t1.id1, '/') AS path_child FROM table_connect_by t1 START WITH t1.id1 = 12 -- specify a main parent to start the selection of sub-children CONNECT BY PRIOR t1.id1 = t1.parent_id1;Query result:
12 12 11 A_11_12 1 /11 /12 12 14 12 A_11_12_14 2 /11/12 /12/14 12 15 12 A_11_12_15 2 /11/12 /12/15 12 16 14 A_11_12_14_16 3 /11/12/14 /12/14/16 12 17 14 A_11_12_14_17 3 /11/12/14 /12/14/17
SELECT CONNECT_BY_ROOT -- specifies the column that will be the parent t1.id1 AS root_parent_id -- the main parent , t1.id1 AS child_id -- children of the main parent , NVL(t1.parent_id1, 0) AS parent_id1 -- direct parent of the selected child , t1.code AS code , LEVEL AS level_parent_child -- distance between the main parent and selected child FROM table_connect_by t1 WHERE LEVEL <= 2 AND t1.id1 != 14 -- add conditions START WITH t1.id1 = 12 -- specify a main parent to start the selection of sub-children CONNECT BY PRIOR t1.id1 = t1.parent_id1;Query result:
12 12 11 A_11_12 1 12 15 12 A_11_12_15 2