Oracle 11g R1 を使用しています。コードは次のとおりです。
CREATE TABLE T1 (ID NUMBER, PARENT_ID NUMBER, LEFT_SIBLING_ID NUMBER);
INSERT INTO T1 VALUES (1,NULL,NULL);
INSERT INTO T1 VALUES (3,1,NULL);
INSERT INTO T1 VALUES (2,1,3);
INSERT INTO T1 VALUES (4,2,NULL);
INSERT INTO T1 VALUES (5,2,4);
INSERT INTO T1 VALUES (10,NULL,1);
INSERT INTO T1 VALUES (12,10,NULL);
INSERT INTO T1 VALUES (11,10,12);
私が望む結果は次のとおりです。
ID-Tree
1
3
2
4
5
10
12
11
ここで重要なのは、通常の PRIOR ID = PARENT_ID 階層の他に、PRIOR ID = LEFT_SIBLING_ID に基づく別の階層があることです。子は、PRIOR ID = LEFT_SIBLING_ID の順にソートされます。そのため、3 の後に 2 が続き、12 の後に 11 が続きます。この順序は重要です。
これを行う方法について空白を描きました。
編集:
順序付けの問題を明確に示すために、さらに行を追加します。
CREATE TABLE T1 (ID NUMBER, PARENT_ID NUMBER, LEFT_SIBLING_ID NUMBER);
INSERT INTO T1 VALUES (1,NULL,10);
INSERT INTO T1 VALUES (3,1,NULL);
INSERT INTO T1 VALUES (2,1,3);
INSERT INTO T1 VALUES (4,2,NULL);
INSERT INTO T1 VALUES (5,2,4);
INSERT INTO T1 VALUES (10,NULL,NULL);
INSERT INTO T1 VALUES (12,10,NULL);
INSERT INTO T1 VALUES (7,10,12);
INSERT INTO T1 VALUES (11,10,7);
INSERT INTO T1 VALUES (6,1,2);
INSERT INTO T1 VALUES (13,1,6);
COMMIT;
クエリの結果:
select substr('----------', 1, lvl*2-2) || to_char(id) id_tree
from
(select SYS_CONNECT_BY_PATH(to_char(id,'009'), ':') sort_path,
left_sibling_id, id, parent_id, level lvl
from t1
start with parent_id is null
connect by prior id = parent_id) q
start with left_sibling_id is null
connect by prior id = left_sibling_id
and coalesce(parent_id,id) = coalesce(parent_id,id)
order by case lvl when 1 then sort_path
else substr(sort_path,1,length(sort_path)-4) end,
level;
ID_TREE
--------------------------------------------------
1
--3
--2
--6
--13
----4
----5
10
--12
--7
--11
11 rows selected
兄弟は適切に並べられていますが (トップ レベルを除く)、もはや親のすぐ下にはありません。