CAFE

SQL Query Tips

connect by level 절

작성자원쿼리맨|작성시간14.03.08|조회수349 목록 댓글 0

본 문제를 정리해 주신 이상옥님에게 감사의 말씀을 드립니다.



아래와 같은 쿼리는 보통 :N 개의 row를 생성하기 위한 row-generator로 사용된다.


SELECT     LEVEL
      FROM DUAL
CONNECT BY LEVEL <= :N


그렇다면, 아래와 같은 쿼리는 몇 개의 row 를 생성할까?
(아래의 인라인뷰 안쪽의 쿼리에서 사용된 connect by level은,
이 글에서 말하고자 하는 주제와는 조금 거리가 있다.
단지 n개의 row를 갖는 테이블을 표현하기 위해 사용되었다고 이해하면 된다.)


SELECT     LEVEL
      FROM (SELECT     *
                  FROM DUAL
            CONNECT BY LEVEL <= 2
)
CONNECT BY LEVEL <= 3


connect by 절은 tree 구조를 나타낼 때 사용하는 구문으로서,
위의 예제로 만들어보면 아래와 같은 구조가 된다.



레벨1   레벨2   레벨3
-----  -----   ----
1
        1
                1
                2
        2
                1
                2
2
        1
                1
                2
        2
                1
                2




일반적으로, RWS 개의 row수를 갖는 테이블 t에 대해서,
아래와 같은 쿼리를 실행하면,


SELECT     LEVEL
      FROM T
CONNECT BY LEVEL <= :LEV



위의 tree 구조의 형태에 따라서,

  lev
   ∑  rws^n
  n=1


개의 row가 생성된다.
위의 예에서 rws=2, lev=3 이므로,

   3
   ∑ 2^n = 2^1 + 2^2 + 2^3 = 2 + 4 + 8 = 14
  n=1

14개의 row가 생성된다.


dual 테이블은 1개의 row를 가지므로,

SELECT     LEVEL
      FROM DUAL
CONNECT BY LEVEL <= :LEV

과 같이 실행해 주면,

  lev
   ∑ 1^n = 1^1 + 1^2 + ... = l * lev = lev
  n=1

즉, 우리가 익히 알고 있는, n개의 row를 생성하게 되는 것이다.



아래의 쿼리에서 로우수(:RWS)와 레벨의 수((:LEV)를 변화시키면서 실행해보고,
3번째 컬럼(TREE)이 만들어 내는 tree 구조를 확인하자.


SELECT     LEVEL
         , RWS
         , LPAD (' ', 4 * (LEVEL - 1), ' ') || RWS TREE
      FROM (SELECT     LEVEL RWS
                  FROM DUAL
            CONNECT BY LEVEL <= :RWS)
CONNECT BY LEVEL <= :LEV


:RWS=3, :LEV=4 일 경우 120개의 row가 생성된다.


TREE
-------------
1
    1
        1
            1
            2
            3
        2
            1
            2
            3
        3
            1
            2
            3
    2
        1
            1
            2
            3
        2
            1
            2
            3
        3
            1
            2
            3
    3
        1
            1
            2
            3
        2
            1
            2
            3
        3
            1
            2
            3
2
    1
        1
            1
            2
            3
        2
            1
            2
            3
        3
            1
            2
            3
    2
        1
            1
            2
            3
        2
            1
            2
            3
        3
            1
            2
            3
    3
        1
            1
            2
            3
        2
            1
            2
            3
        3
            1
            2
            3
3
    1
        1
            1
            2
            3
        2
            1
            2
            3
        3
            1
            2
            3
    2
        1
            1
            2
            3
        2
            1
            2
            3
        3
            1
            2
            3
    3
        1
            1
            2
            3
        2
            1
            2
            3
        3
            1
            2
            3



위의 쿼리는 일반적으로,

:RWS=1 일 때는 :LEV 개의 row를 생성하고,
:RWS>1 일 때는 rws*(rws^lev - 1)/(rws - 1) 개의 row를 생성한다.

다음검색
현재 게시글 추가 기능 열기

댓글

댓글 리스트
맨위로

카페 검색

카페 검색어 입력폼