계층구조에서 특정 값을 기준으로 위, 아래를 선택하는 쿼리 튜닝 관련 문의 0 6 1,223

by DDCC [SQL Query] 계층 구조 sql 튜닝 [2018.05.15 11:57:26]


계층구조관련 sql 문의 드립니다.

## 계층구조 ##

00000
+-10000
| +-10100
| | +-10110
| | | +-10111
| | | +-10112
| | +-10120
| |   +-10122
| |   +-10122
| +-10200
| | +-10210
| | +-10220
| +-10300
|
+-20000
  +-20100
  +-20200


위와 같은 계층 구조에서 
특정 값 "did: 10100"을 기준으로

- 상위: 00000, 10000
- 하위: 10110, 10200, 10111, 10112, 10122, 10122

를 한꺼번에출력하고자 아래와 같은 SQL을 작성하였습니다.
이 방법 말고 더 간단히 출력할 수 있는 쿼리가 있을까요?
도움 부탁 드립니다.

WITH t AS
(
select '00000' did, null pid from dual union all
select '10000' did, '00000' pid from dual union all
select '10100' did, '10000' pid from dual union all
select '10200' did, '10000' pid from dual union all
select '10300' did, '10000' pid from dual union all
select '10110' did, '10100' pid from dual union all
select '10120' did, '10100' pid from dual union all
select '10111' did, '10110' pid from dual union all
select '10112' did, '10110' pid from dual union all
select '10121' did, '10120' pid from dual union all
select '10122' did, '10120' pid from dual union all
select '20000' did, '00000' pid from dual union all
select '20100' did, '20000' pid from dual union all
select '20200' did, '20000' pid from dual
)
SELECT did, pid 
  FROM t
 START WITH did = '10100'
CONNECT BY did = PRIOR pid 
union
SELECT did, pid
  FROM t
 START WITH did = '10100'
CONNECT BY PRIOR did = pid 
order by did
;


 

by 마농 [2018.05.15 13:39:39]

1. UNION
  - UNION 쿼리 2개중 한곳에 WHERE LEVEL != 1 조건을 준다면?
  - UNION 을 UNION ALL 로 바꿀 수 있습니다.
2. 정렬
  - 단순 코드순 정렬만 하면 되는지?
  - 정렬 기준이 명확해야 할 것 같네요.


by DDCC [2018.05.15 14:32:20]

답변 감사합니다.
DID만 반환 결과로 다른 쪽과 조인해야 되서 정렬은 상관없습니다.
start with 문이 2개라 테이블이 큰 경우 속도에 영향이 있을 것 같아
좀더 고급지고 단순한 쿼리가 있을까 하고 문의 드렸던 것입니다.


by 마농 [2018.05.15 14:54:09]

제가 말씀 드린 2가지가 바로 핵심입니다.
 - UNION 을 UNION ALL 로 바꾸기
 - ORDER BY 제거


by DDCC [2018.05.15 15:40:55]

감사합니다. ^^
알려주신 두 가지 적용 하였습니다.
덕분에 큰 팁 알아 갑니다.

SELECT did, pid 
  FROM t
 START WITH did = '10100'
CONNECT BY did = PRIOR pid 
union all
SELECT did, pid
  FROM t
 WHERE LEVEL != 1 
 START WITH did = '10100'
CONNECT BY PRIOR did = pid 

by 마농 [2018.05.15 16:27:33]
-- 시작점을 바꾸면 Where 절을 없앨 수도 있습니다.
SELECT did, pid
  FROM t
-- WHERE LEVEL != 1 
-- START WITH did = '10100'
 START WITH pid = '10100'
 CONNECT BY PRIOR did = pid 
;

 


by DDCC [2018.05.15 17:37:32]

와.. 이걸 이렇게 줄일 수도 있군요.
감사합니다.

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