-- 일단 만들긴 했는데... -- 계층쿼리 특성상 대용량 자료 처리는 힘들지 않을까 생각됩니다. -- rk 값에 따라 적당히 배분하시면 되겠습니다. SELECT r, s, c , svc, sbsc, cust , RANK() OVER(ORDER BY r, s, c) rk FROM ( SELECT svc, sbsc, cust , CONNECT_BY_ROOT(svc) r , CONNECT_BY_ROOT(s) s , CONNECT_BY_ROOT(c) c FROM (SELECT svc, sbsc, cust , LEAST (sbsc, cust) s , GREATEST(sbsc, cust) c , CASE WHEN NOT EXISTS (SELECT 1 FROM t WHERE NOT(svc = a.svc AND sbsc = a.sbsc AND cust = a.cust) AND GREATEST(sbsc, cust) = LEAST(a.sbsc, a.cust) ) AND ROW_NUMBER() OVER( PARTITION BY LEAST(a.sbsc, a.cust) ORDER BY GREATEST(a.sbsc, a.cust) ) = 1 THEN 1 ELSE 0 END root FROM t a ) a START WITH root = 1 CONNECT BY NOCYCLE (PRIOR s = s AND PRIOR c < c) OR (PRIOR c = s AND PRIOR s < s) ) GROUP BY r, s, c, svc, sbsc, cust ;
SELECT r, s, c , svc, sbsc, cust , RANK() OVER(ORDER BY r, s, c) rk FROM ( SELECT svc, sbsc, cust , CONNECT_BY_ROOT(svc) r , CONNECT_BY_ROOT(s) s , CONNECT_BY_ROOT(c) c FROM (SELECT svc, sbsc, cust , LEAST (sbsc, cust) s , GREATEST(sbsc, cust) c , CASE WHEN NOT EXISTS (SELECT 1 FROM t WHERE NOT(svc = a.svc AND sbsc = a.sbsc AND cust = a.cust) AND GREATEST(sbsc, cust) = LEAST(a.sbsc, a.cust) ) AND ROW_NUMBER() OVER( PARTITION BY LEAST(a.sbsc, a.cust) ORDER BY GREATEST(a.sbsc, a.cust) ) = 1 AND ROW_NUMBER() OVER( PARTITION BY GREATEST(a.sbsc, a.cust) ORDER BY LEAST(a.sbsc, a.cust) ) = 1 THEN 1 ELSE 0 END root FROM t a ) a START WITH root = 1 CONNECT BY NOCYCLE (PRIOR s = s AND PRIOR c < c) OR (PRIOR c = c AND PRIOR s < s) OR (PRIOR c = s AND PRIOR s < s) ) GROUP BY r, s, c, svc, sbsc, cust ;
마농님 대단하심. 올려주신 쿼리 이해하기가 힘드네요.. ㅎ
제가 한가지 빠트린게 있네요 그러고 보니..같은 명의자가 복수개의 서비스를 개통하면서 같은 고객을 관련자로 하는 겨우, 즉
WITH T AS (
SELECT 'S1' SVC,111 SBSC,111 CUST FROM DUAL UNION ALL
SELECT 'S1' SVC,111 SBSC,112 CUST FROM DUAL UNION ALL
SELECT 'S1' SVC,111 SBSC,113 CUST FROM DUAL UNION ALL
SELECT 'S2' SVC,112 SBSC,112 CUST FROM DUAL UNION ALL
SELECT 'S2' SVC,112 SBSC,114 CUST FROM DUAL UNION ALL
SELECT 'S2' SVC,112 SBSC,115 CUST FROM DUAL UNION ALL
SELECT 'S3' SVC,116 SBSC,116 CUST FROM DUAL UNION ALL
SELECT 'S4' SVC,116 SBSC,116 CUST FROM DUAL
)
S3,S4 같은 경우도 충분히 있을 수 있네요. 마농님의 주신 쿼리에서 살짝 수정하니 되네요.
답변 감사합니다. 이제 문제는 속도네요 ㅜㅜ
SELECT r, s, c
, svc, sbsc, cust
, RANK() OVER(ORDER BY r, s, c) rk
FROM (
SELECT svc, sbsc, cust
, CONNECT_BY_ROOT(svc) r
, CONNECT_BY_ROOT(s) s
, CONNECT_BY_ROOT(c) c
FROM (
SELECT svc, sbsc, cust
, LEAST (sbsc, cust) s
, GREATEST(sbsc, cust) c
, CASE
WHEN NOT EXISTS
(SELECT 1
FROM t
WHERE NOT(A.SVC = a.svc AND sbsc = a.sbsc AND cust = a.cust)
AND GREATEST(sbsc, cust) = LEAST(a.sbsc, a.cust)
)
AND ROW_NUMBER() OVER(
PARTITION BY LEAST(a.sbsc, a.cust)
ORDER BY A.SVC,GREATEST(a.sbsc, a.cust)
) = 1
AND ROW_NUMBER() OVER(
PARTITION BY GREATEST(a.sbsc, a.cust)
ORDER BY A.SVC,LEAST(a.sbsc, a.cust)
) = 1
THEN 1 ELSE 0
END root
FROM t a
) a
START WITH root = 1
CONNECT BY NOCYCLE (PRIOR s = s AND PRIOR c < c)
OR (PRIOR c = c AND PRIOR s < s)
OR (PRIOR c = s AND PRIOR s < s)
)
GROUP BY r, s, c, svc, sbsc, cust
;
;