Oracle Setup:
CREATE TABLE table_name ( childId, parentId ) AS
SELECT 1, NULL FROM DUAL UNION ALL
SELECT 2, 1 FROM DUAL UNION ALL
SELECT 3, 1 FROM DUAL UNION ALL
SELECT 4, 2 FROM DUAL UNION ALL
SELECT 5, 4 FROM DUAL UNION ALL
SELECT 6, 5 FROM DUAL UNION ALL
SELECT 7, 6 FROM DUAL;
Query:
SELECT childId,
CASE WHEN p02 = 1 THEN NULL WHEN p03 = 1 THEN SUBSTR( path, p02 ) ELSE SUBSTR( path, p02, p03 - p02 - 1 ) END AS Lp1,
CASE WHEN p03 = 1 THEN NULL WHEN p04 = 1 THEN SUBSTR( path, p03 ) ELSE SUBSTR( path, p03, p04 - p03 - 1 ) END AS lp2,
CASE WHEN p04 = 1 THEN NULL WHEN p05 = 1 THEN SUBSTR( path, p04 ) ELSE SUBSTR( path, p04, p05 - p04 - 1 ) END AS lp3,
CASE WHEN p05 = 1 THEN NULL WHEN p06 = 1 THEN SUBSTR( path, p05 ) ELSE SUBSTR( path, p05, p06 - p05 - 1 ) END AS lp4,
CASE WHEN p06 = 1 THEN NULL WHEN p07 = 1 THEN SUBSTR( path, p06 ) ELSE SUBSTR( path, p06, p07 - p06 - 1 ) END AS lp5,
CASE WHEN p07 = 1 THEN NULL WHEN p08 = 1 THEN SUBSTR( path, p07 ) ELSE SUBSTR( path, p07, p08 - p07 - 1 ) END AS lp6
FROM (
SELECT childId,
path,
INSTR( path, '/', 1, 2 ) + 1 AS p02,
INSTR( path, '/', 1, 3 ) + 1 AS p03,
INSTR( path, '/', 1, 4 ) + 1 AS p04,
INSTR( path, '/', 1, 5 ) + 1 AS p05,
INSTR( path, '/', 1, 6 ) + 1 AS p06,
INSTR( path, '/', 1, 7 ) + 1 AS p07,
INSTR( path, '/', 1, 8 ) + 1 AS p08
FROM (
SELECT childId,
SYS_CONNECT_BY_PATH( parentId, '/') AS path
FROM table_name
START WITH parentId IS NULL
CONNECT BY PRIOR childId = parentId
)
);
Output:
CHILDID LP1 LP2 LP3 LP4 LP5 LP6
---------- --- --- --- --- --- ---
1
2 1
4 1 2
5 1 2 4
6 1 2 4 5
7 1 2 4 5 6
3 1
Query 2 - Regular Expressions:
SELECT childId,
TO_NUMBER( REGEXP_SUBSTR( path, '/([^/]*)', 1, 2, NULL, 1 ) ) AS lp1,
TO_NUMBER( REGEXP_SUBSTR( path, '/([^/]*)', 1, 3, NULL, 1 ) ) AS lp2,
TO_NUMBER( REGEXP_SUBSTR( path, '/([^/]*)', 1, 4, NULL, 1 ) ) AS lp3,
TO_NUMBER( REGEXP_SUBSTR( path, '/([^/]*)', 1, 5, NULL, 1 ) ) AS lp4,
TO_NUMBER( REGEXP_SUBSTR( path, '/([^/]*)', 1, 6, NULL, 1 ) ) AS lp5,
TO_NUMBER( REGEXP_SUBSTR( path, '/([^/]*)', 1, 7, NULL, 1 ) ) AS lp6,
TO_NUMBER( REGEXP_SUBSTR( path, '/([^/]*)', 1, 8, NULL, 1 ) ) AS lp7
FROM (
SELECT childId,
SYS_CONNECT_BY_PATH( parentId, '/') AS path
FROM table_name
START WITH parentId IS NULL
CONNECT BY PRIOR childId = parentId
);
SYS_CONNECT_BY_PATH(parentID, '/')"Path" seems like it would work well here... docs.oracle.com/cd/B19306_01/server.102/b14200/queries003.htm