Хорошо, после большого количества ошибок и ошибок я думаю, что нашел решение.
Так что, если у вас есть тестовая таблица, назовите ее xx_tree_test с 3 полями: cd, sup_cd и name; и я добавляю тестовые данные к нему, этот запрос
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;
даст такой результат:
![enter image description here](https://i.stack.imgur.com/pRPjz.png)
Чтобы добавить дополнительный узел, чтобы привести Лист 1 и Лист 2 к одному уровню, вам нужен этот запрос:
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;
Нет, этот запрос даст этот результат:
![enter image description here](https://i.stack.imgur.com/CCuuB.png)
Итак, теперь осталось только упаковать его в красивый вид, чтобы скрыть огромное количество SQL.