CONNECT BY 의 동작순서를 잘 모르겠습니다 0 6 8,419

by 신고의추 [Oracle 기초] ORACLE CONNECT BY PRIOR [2015.12.15 15:44:42]


CONNECT BY 를 어제부터 이해하려했지만 아직까지 이해를 못하였네요.

동작 순서가 궁금해서 이것저것 다 해보았고 검색도 해보았지만 원하는 답을 찾을수가 없네요.

WITH test_a as( -- 쿼리1
          SELECT 'B' code FROM dual
          UNION ALL
          SELECT 'C' code FROM dual
          UNION ALL
          SELECT 'A' code FROM dual
          )
SELECT SUBSTR(SYS_CONNECT_BY_PATH(code, '-'), 2) codes
          ,PRIOR code, code, LEVEL
FROM test_a
CONNECT BY nocycle PRIOR code != code
;

위의 쿼리를 실행하면 B C A 의 경우의 수가 모두 나오게 되며

순서는 컬럼에 입력된 B-> C-> A 순으로 데이터가 나옵니다.

 

WITH test_a as( -- 쿼리2
          SELECT 'B' code FROM dual
          UNION ALL
          SELECT 'C' code FROM dual
          UNION ALL
          SELECT 'A' code FROM dual
          )
SELECT SUBSTR(SYS_CONNECT_BY_PATH(code, '-'), 2) codes
          ,PRIOR code, code, LEVEL
FROM test_a
CONNECT BY PRIOR code < code
;
WITH test_a as( -- 쿼리3
          SELECT 'B' code FROM dual
          UNION ALL
          SELECT 'C' code FROM dual
          UNION ALL
          SELECT 'A' code FROM dual
          )
SELECT SUBSTR(SYS_CONNECT_BY_PATH(code, '-'), 2) codes
          ,PRIOR code, code, LEVEL
FROM test_a
CONNECT BY PRIOR code > code
;

그런데 쿼리2와 3은 부등호에 따라 자동으로 A~C 와 C~A로 순서가 바뀌어 나오더군요.

 

쿼리1 처럼 컬럼의 로우순으로 순차적으로 접근 하는줄 알았는데

부등호에서 달라지니 생각했던 순서가 물거품이 되었습니다.

 

질문1) CONNECT BY 뒤의 조건이 false면 해당 데이터는 출력이 안되고 다음 계층으로 가지 않는게 맞나요?

질문2) CONNECT BY 뒤의 조건이 unknow면 실행을 하는것인가요?

질문3) 위의 쿼리1,2,3의 동작순서가 차이나는 이유가 궁금합니다

 

by 마농 [2015.12.15 16:20:02]

질문 1,2 는 뭔 얘기 하시는지 모르겠고...(이전 질문부터 true/ false 로 헷갈리게 하십니다.)

질문3 은...

정렬결과가 중요한게 아니고 전체 결과가 올바른지?를 보시면 됩니다.
  - 결과만 맞다면? 내부 처리 과정은 가장 효율이 좋은 방법을 선택할 것입니다.
  - 선택된 처리 방법에 따라 정렬 순서가 달라지기도 합니다.
  - 11G 에서는 ABC 순서로 10G 에서는 BCA 순서로 수행되네요.
  - 11G에서 향상된 처리과정을 거치는 듯 하긴 한데
  - 사용자 입장에서는 내부적인 처리과정까지 알 필요는 없죠.
  - 구문이 처리되는 과정, 논리적인 처리 흐름만 알면 됩니다.


by 겸댕2후니 [2015.12.15 16:27:17]

마농님, 그렇다면

1번쿼리의 결과값은, 실제 Row순서에 따라 결과가 달라지는게 맞나요??

작성자분이 쓰신 쿼리의 Row 순서는 B, C, A인데

1번쿼리의 결과는   

level   code

1        B

2        C

3        A

 

일텐데.. 만약 A, B, C순서로 바뀌면

level   code

1        A

2        B

3        C

 

가 되는게 맞나요?


by 신고의추 [2015.12.15 16:40:17]

이번 질문에서도 제가 true/false에 연연했네요.

1번은 CONNECT BY 뒤의 조건식이 무엇에 영향을 주는건지 궁금했었습니다.

2번은 실행 중에

PRIOR code는 NULL이고 code는 'A' 인 경우에

PRIOR code < code 는 unknown으로 나올거같은데

왜 결과에 같이 나왔는지에 대한 궁금증이였습니다. ( A,B,C 가 혼자 나온경우)

3번은 역시나 내부적인 문제였군요. 전 제가 잘못 이해하고있는줄 알았습니다. 덕분에 어느정도 해결이 되었네요. 궁금한게 생기면 이경우 저경우 다 메달리다보니 머리만 아프고 .. 아직 이해못한게 남았지만 일단은 다음으로 넘어갈수 있겠네요.

오늘도 답변 감사합니다


by 마농 [2015.12.15 16:51:02]

내부적인 처리과정은 중요한게 아니고 논리적인 처리 흐름을 살펴보면
계층쿼리의 처리순서는 다음과 같습니다.

SELECT *                    -- 5
  FROM t                    -- 1
 WHERE 1=1                  -- 4
 START WITH cd IS NULL      -- 2
 CONNECT BY PRIOR cd = pcd  -- 3
;

1. Start With 조건에 맞는 자료로부터 계층구조가 시작되구요
2. Connect By 조건에 맞는 자료를 찾아 계층구조를 전개합니다.
3. Where 조건은 계층 전개 후에 체크됩니다.


질문의 예 에서는 시작조건이 없으므로 3개 행이 모두 1레벨이 됩니다.
이후 계층전개조건에 맞는 자료를 찾죠
CONNECT BY PRIOR code < code 를 예로 설명하면
1레벨은 A, B, C 이며
2레벨은
 - A 보다큰 B, C : 경로로 표시하면 A-B, A-C
 - B 보다 큰 C : 경로로 표시하면 B-C
3레벨은 A-B 의 B 보다 큰 C : A-B-C
이런식으로 전개되는 것입니다.


by 마농 [2015.12.15 17:02:56]

겸댕2후니님 질문에 대한 답변
1번쿼리의 결과값은, 실제 Row순서에 따라 결과가 달라지는게 맞나요??
  - 결과가 달라지는게 아닙니다.
  - 정렬 순서만 다른 것 뿐입니다.
2. 제시하신 쿼리 결과는?
  - 그렇게 나오는게 아닙니다.
  - 직접 한번 수행해 보세요.


by 겸댕2후니 [2015.12.15 17:43:52]

제가 착각했었네요.

답변 감사합니다^^

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