아래의 계층 구조에서 siblings으로 자식들의 순서가 결정이 되는데 이 순서의 값을 결과에서 나타내고 싶습니다.
with t as (
select '-' parent, '001' item, 'abc' dsc, 0 seq from dual union all
select '001' , '002', 'abc', 1 from dual union all
select '002' , '003', 'abc', 2 from dual union all
select '002' , '004', 'abc', 3 from dual union all
select '002' , '004', 'efg', 4 from dual union all
select '002' , '004', 'bcd', 5 from dual union all
select '002' , '005', 'abc', 6 from dual
)
select parent, item, dsc, seq from t
start with parent = '-'
connect by prior item = parent
ORDER SIBLINGS BY parent, item, dsc;
parent, item, dsc, seq, child_seq
- 001 abc 0, 0
001 002 abc 1, 1
002 003 abc 2, 1
002 004 abc 3, 1
002 004 bcd 5, 2
002 004 efg 4, 3
002 005 abc 6, 1
부모 002의 자식들중 속성 dsc는 다르지만 item 004가 3번 나옵니다.
이들을 dsc로 sort하고 그들간의 순서를 주고 싶습니다.
1. ORDER SIBLINGS BY 는
- 동일 부모 아래 자식들끼리의 순서를 정하는 구문이므로
- 여기에 부모를 정렬 기준으로 넣는 것은 무의미합니다.
2. 원하시는 child_seq 는
- 동일 아이디 간에 순번을 정하는 것으로
- ROW_NUMBER 을 이용해 구할 수 있습니다.
-- 1. child_seq 먼저 구한 뒤 계층 전개 -- SELECT * FROM (SELECT parent, item, dsc, seq , ROW_NUMBER() OVER(PARTITION BY item ORDER BY dsc) child_seq FROM t ) START WITH parent = '-' CONNECT BY PRIOR item = parent ORDER SIBLINGS BY item, dsc ; -- 2. 계층 쿼리 후 child_seq 구하기 -- 단, 정렬을 유지하기 위해서는 Rownum 을 이용해 다시 정렬해야 함 SELECT parent, item, dsc, seq , ROW_NUMBER() OVER(PARTITION BY item ORDER BY dsc) child_seq FROM (SELECT parent, item, dsc, seq , ROWNUM rn FROM t START WITH parent = '-' CONNECT BY PRIOR item = parent ORDER SIBLINGS BY item, dsc ) ORDER BY rn ;
with temp_t as ( select '-' parent, '001' item, 'abc' dsc, 0 seq from dual union all select '001' , '002', 'abc', 1 from dual union all select '002' , '003', 'abc', 2 from dual union all select '002' , '004', 'abc', 3 from dual union all select '002' , '004', 'efg', 4 from dual union all select '002' , '004', 'bcd', 5 from dual union all select '002' , '005', 'abc', 6 from dual union all select '005' , '001', 'loop', 7 from dual -- LOOPING ITEM ) , EXPL_T (PARENT ,ITEM ,DSC ,SEQ ,LEVL ,CH_SEQ ,PATH) AS ( SELECT PARENT ,ITEM ,DSC ,SEQ ,0 ,0 ,ITEM FROM TEMP_T WHERE PARENT = '-' UNION ALL SELECT T.PARENT ,T.ITEM ,T.DSC ,T.SEQ ,E.LEVL + 1 ,ROW_NUMBER() OVER ( PARTITION BY T.PARENT,T.ITEM ORDER BY T.DSC NULLS FIRST ,T.SEQ) ,E.PATH ||'/'|| T.ITEM FROM TEMP_T T ,EXPL_T E WHERE T.PARENT = E.ITEM ) SEARCH DEPTH FIRST BY ITEM ,DSC NULLS FIRST ,SEQ SET ORDER_N -- 깊이 순서 --SEARCH BREADTH FIRST BY ITEM ,DSC NULLS FIRST ,SEQ SET ORDER_N -- 폭 순서 CYCLE ITEM SET CYCL_SW TO 'L' DEFAULT ' ' -- LOOP 처리 SELECT E.* FROM EXPL_T E WHERE 1=1 AND CYCL_SW = ' ' -- LOOP 제외