같은 부품이 여러번 같은 부모에 붙어 있을때 속성을 정렬하고 순번주기 1 2 1,004

by MS [SQL Query] [2019.04.15 14:14:19]


아래의 계층 구조에서 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하고 그들간의 순서를 주고 싶습니다.

by 마농 [2019.04.15 14:50:57]

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
;

 


by 색즉시공 [2019.04.21 09:17:55]
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 제외
 

 

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입