본 문제를 정리해 주신 이상옥님에게 감사의 말씀을 드립니다.
아래와 같은 쿼리는 보통 :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를 생성한다.