Ok, después de mucho camino y error, creo que encontré la solución.
Entonces, si tiene una tabla de prueba, llámela xx_tree_test con 3 campos: cd, sup_cd y name; y añado los datos de prueba a la misma, esta consulta
SELECT CD,
SUP_CD,
LEVEL AS LVL,
CASE WHEN CONNECT_BY_ISLEAF = 1 THEN 'L' ELSE NULL END AS LEAF,
LPAD (' ', 3 * LEVEL, ' .') || NAME AS NAME
FROM xx_tree_test
START WITH SUP_CD IS NULL
CONNECT BY PRIOR CD = SUP_CD;
que le dará este resultado:
para agregar el nodo adicional para llevar la hoja 1 y 2 de la hoja al mismo nivel que necesita esta consulta:
SELECT CD,
SUP_CD,
LEVEL AS LVL,
CASE WHEN CONNECT_BY_ISLEAF = 1 THEN 'L' ELSE NULL END AS LEAF,
LPAD (' ', 3 * LEVEL, ' .') || NAME AS NAME
FROM (WITH FULL_TREE
AS ( SELECT CD,
SUP_CD,
LEVEL AS LVL,
CASE
WHEN CONNECT_BY_ISLEAF = 1 THEN 'L'
ELSE NULL
END
AS LEAF,
LPAD (' ', 3 * LEVEL, ' .') || NAME AS TREE_NAME,
NAME
FROM XX_TREE_TEST
START WITH SUP_CD IS NULL
CONNECT BY PRIOR CD = SUP_CD)
SELECT A.NAME,
A.CD,
A.SUP_CD,
A.LVL
FROM FULL_TREE A
WHERE NVL (LEAF, 'z') != 'L'
UNION ALL
SELECT CASE
WHEN TREE1.LVL + TREE2.ROW_NUM_GENERATED - 1 =
(SELECT MAX (LVL) FROM FULL_TREE)
THEN
TREE1.NAME
ELSE
'Copy of ' || TREE1.NAME
END
AS NAME,
CASE
WHEN TREE1.LVL + TREE2.ROW_NUM_GENERATED - 1 =
(SELECT MAX (LVL) FROM FULL_TREE)
THEN
CD
ELSE
CD || '`' || TO_CHAR (TREE2.ROW_NUM_GENERATED)
END
AS CD,
CASE
WHEN TREE2.ROW_NUM_GENERATED = 1 THEN SUP_CD
ELSE CD || '`' || TO_CHAR (TREE2.ROW_NUM_GENERATED - 1)
END
AS SUP_CD,
TREE1.LVL + TREE2.ROW_NUM_GENERATED AS LVL
FROM (SELECT FULL_TREE.NAME,
FULL_TREE.CD,
FULL_TREE.SUP_CD,
FULL_TREE.LVL
FROM FULL_TREE
WHERE LEAF = 'L') TREE1
JOIN
( SELECT LEVEL AS ROW_NUM_GENERATED
FROM DUAL
CONNECT BY LEVEL <= (SELECT MAX (LVL) FROM FULL_TREE)) TREE2
ON (SELECT MAX (LVL) FROM FULL_TREE) + 1 >=
TREE2.ROW_NUM_GENERATED + TREE1.LVL
ORDER BY CD, LVL)
START WITH SUP_CD IS NULL
CONNECT BY PRIOR CD = SUP_CD;
Sin esta consulta que le dará este resultado:
Todo lo que queda por hacer ahora es simplemente empaquetarlo en una bonita vista para ocultar las enormes cantidades de SQL.