by 동동동 [SQL Query] Oracle CONNECT BY [2021.07.21 16:09:52]
안녕하세요..CONNECT BY로 계층구조 형식으로 데이터 표현시 상위 중복코드가 존재시 하나의 상위에만 하위를 표시할 수 있을까요?
WITH TMP AS ( SELECT 'A' CD, 'A' NM, 'A' UP_CD, 1 LV, 1 RN FROM DUAL UNION ALL SELECT 'A1' , 'A1' , 'A' , 2 LV, 2 RN FROM DUAL UNION ALL SELECT 'A1' , 'A2' , 'A' , 2 LV, 3 RN FROM DUAL UNION ALL SELECT 'A1A' , 'A1A' , 'A1' , 3 LV, 4 RN FROM DUAL UNION ALL SELECT 'A1B' , 'A1B' , 'A1' , 3 LV, 5 RN FROM DUAL UNION ALL SELECT 'B' , 'B' , 'B' , 1 LV, 1 RN FROM DUAL UNION ALL SELECT 'B1' , 'B1' , 'B' , 2 LV, 2 RN FROM DUAL UNION ALL SELECT 'B1A' , 'B1A' , 'B1' , 3 LV, 3 RN FROM DUAL ) SELECT A.* , LPAD(' ',4*(LEVEL-1))||A.NM TREE_NM FROM TMP A START WITH A.LV = '1' CONNECT BY NOCYCLE PRIOR A.CD = A.UP_CD ORDER SIBLINGS BY A.LV;
CD | NM | UP_CD | LV | RN | TREE_NM |
A | A | A | 1 | 1 | A |
A1 | A1 | A | 2 | 2 | A1 |
A1A | A1A | A1 | 3 | 4 | A1A |
A1B | A1B | A1 | 3 | 5 | A1B |
A1 | A2 | A | 2 | 3 | A2 |
A1A | A1A | A1 | 3 | 4 | A1A |
A1B | A1B | A1 | 3 | 5 | A1B |
B | B | B | 1 | 1 | B |
B1 | B1 | B | 2 | 2 | B1 |
B1A | B1A | B1 | 3 | 3 | B1A |
다음과 같이 A1이라는 중복코드가 있을시 해당 하위코드는 둘중 RN이 가장 작거나 가장 큰 곳에 한번만 나타나게 할 수 있을까요?
원하는 값
CD | NM | UP_CD | LV | RN | TREE_NM |
A | A | A | 1 | 1 | A |
A1 | A1 | A | 2 | 2 | A1 |
A1 | A2 | A | 2 | 3 | A2 |
A1A | A1A | A1 | 3 | 4 | A1A |
A1B | A1B | A1 | 3 | 5 | A1B |
B | B | B | 1 | 1 | B |
B1 | B1 | B | 2 | 2 | B1 |
B1A | B1A | B1 | 3 | 3 | B1A |
도움 부탁 드립니다..
억지로 예외처리하는 로직을 구현할 수는 있겠지만
그것보다는 중복자료를 찾아 바로잡는게 맞다고 생각합니다.
WITH tmp AS ( SELECT 'A' cd, 'A' nm, 'A' up_cd, 1 lv, 1 rn FROM dual UNION ALL SELECT 'A1' , 'A1' , 'A' , 2, 2 FROM dual UNION ALL SELECT 'A1' , 'A2' , 'A' , 2, 3 FROM dual UNION ALL SELECT 'A1A', 'A1A', 'A1', 3, 4 FROM dual UNION ALL SELECT 'A1B', 'A1B', 'A1', 3, 5 FROM dual UNION ALL SELECT 'B' , 'B' , 'B' , 1, 1 FROM dual UNION ALL SELECT 'B1' , 'B1' , 'B' , 2, 2 FROM dual UNION ALL SELECT 'B1A', 'B1A', 'B1', 3, 3 FROM dual ) SELECT cd, nm, up_cd, lv, rn , LPAD(' ', (LEVEL-1)*4) || nm tree_nm FROM (SELECT cd, nm, up_cd, lv, rn , ROW_NUMBER() OVER(PARTITION BY cd ORDER BY rn) x FROM tmp ) START WITH lv = '1' CONNECT BY NOCYCLE PRIOR cd = up_cd AND PRIOR x = 1 ORDER SIBLINGS BY rn ;