好吧,經過大量的跟蹤和錯誤,我想我找到了解決方案。
所以如果你有一個測試表叫它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;
會產生這樣的結果:
添加額外的節點,使葉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;
沒有這個查詢會產生這樣的結果:
所以現在要做的只是將它打包成一個很好的視圖來隱藏大量的SQL。