마농님 추가 질문 드립니다. 0 7 2,328

by 손님 [SQL Query] tree [2011.02.16 18:42:50]


안녕하세요. 마농님~~
아래 소스중 이해 않되는 부분이 있습니다.

lv-1 PRECEDING -- 제가 이해하기에는 이전에 나왔던 부모의 데이타.
DECODE(1
, MAX(MAX(flag)) OVER(PARTITION BY root_id ORDER BY lv ROWS BETWEEN lv-1 PRECEDING AND 1 PRECEDING)
, 0, MAX(flag)
) v

아래 예제는 트리가 두개이고 각 트리의 루트가 한개 존재(여러개도 존재).
제대로 계산을 못하네요.
제가 마농님 쿼리를 이해하지 못해서 수정이 힘드네요.
도움 부탁드립니다.
감사합니다.


with t as
(
select 2 id, 1 upper_id,'155M' nm,'02' stat,1 CHNL from dual
union all select 6, 2 ,'51M','01',1 from dual
union all select 7, 2 ,'51M','01',1 from dual
union all select 8, 2 ,'51M','02',1 from dual
union all select 9, 2 ,'51M','05',1 from dual
union all select 10, 2 ,'51M','01',1 from dual
union all select 11, 2 ,'51M','01',1 from dual
union all select 12, 2 ,'51M','08',1 from dual
union all select 13, 2 ,'51M','01',1 from dual
union all select 14, 6 ,'2M','05',1 from dual
union all select 15, 6 ,'2M','08',1 from dual
union all select 16, 6 ,'2M','01',1 from dual
union all select 17, 6 ,'2M','03',1 from dual
union all select 18, 7 ,'2M','01',1 from dual
union all select 19, 7 ,'2M','01',1 from dual
union all select 20, 7 ,'2M','01',1 from dual
union all select 21, 7 ,'2M','01',1 from dual
union all select 22, 8 ,'2M','08',1 from dual
union all select 23, 8 ,'2M','03',1 from dual
union all select 24, 8 ,'2M','01',1 from dual
union all select 25, 8 ,'2M','01',1 from dual
union all select 26, 9 ,'2M','01',1 from dual
union all select 27, 9 ,'2M','01',1 from dual
union all select 28, 9 ,'2M','01',1 from dual
union all select 29, 9 ,'2M','01',1 from dual

union all select 2 , 1 ,'155M' ,'02' ,2  from dual
union all select 6, 2 ,'51M','01',2 from dual
union all select 7, 2 ,'51M','01',2 from dual
union all select 8, 2 ,'51M','02',2 from dual
union all select 9, 2 ,'51M','05',2 from dual
union all select 10, 2 ,'51M','01',2 from dual
union all select 11, 2 ,'51M','01',2 from dual
union all select 12, 2 ,'51M','08',2 from dual
union all select 13, 2 ,'51M','01',2 from dual
union all select 22, 8 ,'2M','08',2 from dual
union all select 23, 8 ,'2M','03',2 from dual
union all select 24, 8 ,'2M','01',2 from dual
union all select 25, 8 ,'2M','01',2 from dual
union all select 26, 9 ,'2M','01',2 from dual
union all select 27, 9 ,'2M','01',2 from dual
union all select 28, 9 ,'2M','01',2 from dual
union all select 29, 9 ,'2M','01',2 from dual
union all select 30, 10 ,'2M','05',2 from dual
union all select 31, 10 ,'2M','01',2 from dual
union all select 32, 10 ,'2M','01',2 from dual
union all select 33, 10 ,'2M','01',2 from dual
union all select 34, 11 ,'2M','03',2 from dual
union all select 35, 11 ,'2M','01',2 from dual
union all select 36, 11 ,'2M','08',2 from dual
union all select 37, 11 ,'2M','01',2 from dual
union all select 42, 13 ,'2M','01',2 from dual
union all select 43, 13 ,'2M','01',2 from dual
union all select 44, 13 ,'2M','01',2 from dual
union all select 45, 13 ,'2M','01',2 from dual
)
SELECT lv, nm
, SUM(v) cnt
FROM
(
SELECT lv, nm
, DECODE(1
, MAX(MAX(flag)) OVER(PARTITION BY root_id ORDER BY lv ROWS BETWEEN lv-1 PRECEDING AND 1 PRECEDING)
, 0, MAX(flag)
) v
FROM
(
SELECT nm
, LEVEL lv
, CONNECT_BY_ROOT(id) root_id
, DECODE(stat, '03', 1, '08', 1, 0) flag
FROM t
START WITH upper_id = 1
CONNECT BY PRIOR id = upper_id
)
GROUP BY root_id, lv, nm
)
GROUP BY lv, nm
ORDER BY lv, nm
;

by 쌩초보 [2011.02.16 18:51:14]
처음에 했던 데이타 입니다.
with t as
(
select 2 id, 1 upper_id,'155M' nm,'03' stat from dual
union all select 3, 1 ,'155M','01' from dual
union all select 4, 1 ,'155M','02'from dual
union all select 5, 1 ,'155M','01' from dual
union all select 6, 2 ,'51M','01' from dual
union all select 7, 2 ,'51M','01' from dual
union all select 8, 2 ,'51M','02' from dual
union all select 9, 2 ,'51M','03' from dual
union all select 10, 4 ,'51M','01' from dual
union all select 11, 4 ,'51M','01' from dual
union all select 12, 5 ,'51M','08' from dual
union all select 13, 5 ,'51M','01' from dual
union all select 14, 6 ,'2M','05' from dual
union all select 15, 6 ,'2M','08' from dual
union all select 16, 6 ,'2M','01' from dual
union all select 17, 6 ,'2M','03' from dual
union all select 18, 7 ,'2M','01' from dual
union all select 19, 7 ,'2M','01' from dual
union all select 20, 7 ,'2M','01' from dual
union all select 21, 7 ,'2M','01' from dual
union all select 22, 8 ,'2M','08' from dual
union all select 23, 8 ,'2M','03' from dual
union all select 24, 8 ,'2M','01' from dual
union all select 25, 8 ,'2M','01' from dual
union all select 26, 9 ,'2M','01' from dual
union all select 27, 9 ,'2M','01' from dual
union all select 28, 9 ,'2M','01' from dual
union all select 29, 9 ,'2M','01' from dual
union all select 30, 10 ,'2M','05' from dual
union all select 31, 10 ,'2M','01' from dual
union all select 32, 10 ,'2M','01' from dual
union all select 33, 10 ,'2M','01' from dual
union all select 34, 11 ,'2M','03' from dual
union all select 35, 11 ,'2M','01' from dual
union all select 36, 11 ,'2M','08' from dual
union all select 37, 11 ,'2M','01' from dual
union all select 38, 12 ,'2M','03' from dual
union all select 39, 12 ,'2M','03' from dual
union all select 40, 12 ,'2M','01' from dual
union all select 41, 12 ,'2M','01' from dual
union all select 42, 13 ,'2M','01' from dual
union all select 43, 13 ,'2M','01' from dual
union all select 44, 13 ,'2M','01' from dual
union all select 45, 13 ,'2M','01' from dual
)

by 쌩초보 [2011.02.16 19:06:54]
155M,51M,2M중에 03,08이 아무리 많이 존재해도 셋중에 어느 한개만 1을 가져야 됩니다. 왜냐하면 155M가 한개이기 때문입니다. 만약 여러개이면 최대 155M 갯수만큼 1을 가집니다. 155M 자손은 부모 부터 값을 따져 가면서 값이 존재하는(03,08) 최상의 노드만 1을 가집니다.

by 마농 [2011.02.17 08:05:11]
chnl에 대해서 추가 질문 했었죠?
그부분에 대한 답변 드렸었는데.. 전혀 그부분이 반영이 안되어 있네요.
지금 쿼리는 root 를 기준으로 하는 쿼리입니다만.
개선해야할 쿼리는 chnl, root 를 기준으로 해야하겠죠.

CONNECT BY PRIOR id = upper_id ===> CONNECT BY PRIOR id = upper_id AND PRIOR chnl = chnl
GROUP BY root_id, lv, nm ===> GROUP BY chnl, root_id, lv, nm
PARTITION BY root_id ===> PARTITION BY chnl, root_id

by 쌩초보 [2011.02.17 11:35:35]
도움 주셔서 감사합니다.
아래와 같은 데이타는 결과값이 이상합니다.
제가 편의상 숫자로 변환 했습니다.
17 : 루트가 한개 이니까 26의 값은 1이 나와야 되는데
3이 나옵니다.
실제 데이타를 가져와서 만든겁니다.
감사합니다.

with t as
(
select 1 id, 0 upper_id,17 nm,'02' stat,1 CHNL from dual
union all select 2, 1 ,21,'01',1 from dual
union all select 3, 1 ,21,'01',1 from dual
union all select 4, 1 ,21,'02',1 from dual
union all select 5, 2 ,25,'05',1 from dual
union all select 6, 2 ,25,'01',1 from dual
union all select 7, 2 ,25,'01',1 from dual
union all select 8, 3 ,25,'01',1 from dual
union all select 9, 3 ,25,'01',1 from dual
union all select 10, 3 ,25,'01',1 from dual
union all select 11, 4 ,25,'01',1 from dual
union all select 12, 4 ,25,'05',1 from dual
union all select 13, 4 ,25,'01',1 from dual
union all select 14, 5 ,26,'01',1 from dual
union all select 15, 5 ,26,'03',1 from dual
union all select 16, 5 ,26,'01',1 from dual
union all select 17, 5 ,26,'01',1 from dual
union all select 18, 6 ,26,'01',1 from dual
union all select 19, 6 ,26,'01',1 from dual
union all select 20, 6 ,26,'01',1 from dual
union all select 21, 6 ,26,'01',1 from dual
union all select 22, 7 ,26,'03',1 from dual
union all select 23, 7 ,26,'01',1 from dual
union all select 24, 7 ,26,'01',1 from dual
union all select 25, 7 ,26,'01',1 from dual
union all select 26, 8 ,26,'01',1 from dual
union all select 27, 8 ,26,'01',1 from dual
union all select 28, 8 ,26,'08',1 from dual
union all select 29, 8 ,26,'03',1 from dual
union all select 30, 9 ,26,'01',1 from dual
union all select 25, 9 ,26,'01',1 from dual
union all select 26, 9 ,26,'01',1 from dual
union all select 27, 9 ,26,'01',1 from dual
union all select 28, 10 ,26,'01',1 from dual
union all select 29, 10 ,26,'03',1 from dual
union all select 30, 10 ,26,'01',1 from dual
union all select 31, 10 ,26,'01',1 from dual
union all select 32, 11 ,26,'01',1 from dual
union all select 33, 11 ,26,'01',1 from dual
union all select 34, 11 ,26,'01',1 from dual
union all select 35, 11 ,26,'08',1 from dual
union all select 36, 12 ,26,'03',1 from dual
union all select 37, 12 ,26,'01',1 from dual
union all select 38, 12 ,26,'01',1 from dual
union all select 39, 12 ,26,'01',1 from dual
union all select 40, 13 ,26,'01',1 from dual
union all select 41, 13 ,26,'01',1 from dual
union all select 42, 13 ,26,'01',1 from dual
union all select 43, 13 ,26,'01',1 from dual
)

by 쌩초보 [2011.02.17 11:36:19]
SELECT lv, nm
, SUM(v) cnt
,CHNL
FROM
(
SELECT lv, nm
, DECODE(1
, MAX(MAX(flag)) OVER(PARTITION BY CHNL,root_id ORDER BY lv ROWS BETWEEN lv-1 PRECEDING AND 1 PRECEDING)
, 0, MAX(flag)
) v
,CHNL
FROM
(
SELECT nm
, LEVEL lv
, CONNECT_BY_ROOT(id) root_id
, DECODE(stat, '03', 1, '08', 1, 0) flag
,CHNL
FROM t
START WITH upper_id = 1
CONNECT BY PRIOR id = upper_id
AND PRIOR CHNL = CHNL
)
GROUP BY CHNL,root_id, lv, nm
)
GROUP BY CHNL,lv, nm
ORDER BY CHNL,lv, nm
;

by 마농 [2011.02.17 11:42:04]
쿼리를 이해하셔야 상황에 대처를 하지요.
지금은 계층구조의 시작점이 1 이 아니라 0 이죠.
START WITH upper_id = 1 ===> START WITH upper_id = 0

by 쌩초보 [2011.02.17 12:39:40]
이런.. 실수를..... 잘 되네요. 근데 왜 제소스는 3이 나올까요... 미치겠네 ㅎㅎ
도움 주셔서 감사합니다.
댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입