by 마농 계층구조쿼리 CONNECT BY LEVEL SYS_CONNECT_BY_PATH PRIOR NOCYCLE 테스트데이터생성 경우의수 [2014.01.17]
아래는 현재행을 시작점으로 하위에서 상위로 누적합계를 구하는 예제이다.
SELECT empno , LEVEL lv , LPAD(' ', (LEVEL-1)*2, ' ') || ename AS ename , sal , (SELECT SUM(sal) FROM emp START WITH empno = a.empno CONNECT BY PRIOR empno = mgr ) sum_sal FROM emp a START WITH mgr IS NULL CONNECT BY PRIOR empno = mgr ; EMPNO LV ENAME SAL SUM_SAL ------- ---------- -------------------- ---------- ---------- 7839 1 KING 5000 29025 7566 2 JONES 2975 10875 7788 3 SCOTT 3000 4100 7876 4 ADAMS 1100 1100 7902 3 FORD 3000 3800 7369 4 SMITH 800 800 7698 2 BLAKE 2850 9400 7499 3 ALLEN 1600 1600 7521 3 WARD 1250 1250 7654 3 MARTIN 1250 1250 7844 3 TURNER 1500 1500 7900 3 JAMES 950 950 7782 2 CLARK 2450 3750 7934 3 MILLER 1300 1300
프로젝트 진행시 테스트 데이터 생성이 필요한 경우가 있는데 CONNECT BY LEVEL을 활용하면 손쉽게 테스트 샘플 데이터를 생성 할 수 있다.
아래 예제와 같이 CONNECT BY LEVEL을 사용하면, 특정 LEVEL이 될 때 까지 ROW를 출력하는 것을 알 수 있다.
-- 10개의 ROW를 출력하는 예제이다. SELECT LEVEL FROM DUAL CONNECT BY LEVEL <= 10; -- 10개의 ROW가 출력된다. LEVEL ------- 1 2 3 4 ... 10
위 CONNECT BY LEVEL의 원리를 이용하여 아래와 같이 테스트 샘플데이터를 만들어 보자
-- 10 만건의 데이터를 가지는 emp_sample 테이블을 생성하는 예제이다. CREATE TABLE emp_sample AS SELECT -- 1. EMPNO(Unique 컬럼) LEVEL empno, -- 2. JOB(천만건 데이터를 10개 그룹으로 분류) 'SALESMAN_'||CHR(65 + MOD(LEVEL , 10)) job, -- 3. HIREDATE(금일+9일까지) SYSDATE + MOD(LEVEL , 10) hiredate, -- 4. DEPTNO (0, 10, 20, 30, 40) MOD(LEVEL ,5)*10 deptno FROM DUAL CONNECT BY LEVEL <= 100000; -- 테이블과 데이터가 정상적으로 생성되었는지 확인해 보자 SELECT * FROM emp_sample WHERE ROWNUM < 10; EMPNO JOB HIREDATE DEPTNO ----- ----------- -------- ---------- 1 SALESMAN_B 11/06/28 10 2 SALESMAN_C 11/06/29 20 3 SALESMAN_D 11/06/30 30 4 SALESMAN_E 11/07/01 40 ...
이번 예제는 그림과 같이 (A, B, C) 3개 코드 조합으로 나올 수 있는 모든 경우의 수를 조회하는 예제이다.
아래는 계층구조쿼리를 사용하지 않고, UNION ALL을 이용하여 작성하였다. 아래 쿼리는 self 조인과 UNION ALL 조합의 한계가 있다. 코드의 개수가 늘어날 경우 SQL 수정이 불가피 하다.
WITH test AS ( SELECT 'A' code FROM dual UNION ALL SELECT 'B' FROM dual UNION ALL SELECT 'C' FROM dual ) SELECT a.code FROM test a UNION ALL SELECT a.code ||'-'|| b.code AS code FROM test a , test b WHERE a.code < b.code UNION ALL SELECT a.code ||'-'|| b.code ||'-'|| c.code AS code FROM test a , test b , test c WHERE a.code < b.code AND b.code < c.code ; CODE --------------- A B C A-B A-C B-C A-B-C 7 rows selected.
아래는 계층구조쿼리를 사용하여 경우의 수를 조회한 예제이다.
WITH test AS ( SELECT 'A' code FROM dual UNION ALL SELECT 'B' FROM dual UNION ALL SELECT 'C' FROM dual ) SELECT SUBSTR(SYS_CONNECT_BY_PATH(code, '-'), 2) code FROM test CONNECT BY PRIOR code < code ORDER BY LEVEL, code ; CODE ----------------- A B C A-B A-C B-C A-B-C 7 rows selected.
이번 예제는 순서까지 고려한 모든 경우의 수이다.
WITH test AS ( SELECT 'A' code FROM dual UNION ALL SELECT 'B' FROM dual UNION ALL SELECT 'C' FROM dual ) SELECT SUBSTR(SYS_CONNECT_BY_PATH(code, '-'), 2) code FROM test CONNECT BY NOCYCLE PRIOR code != code ORDER BY LEVEL, code ; CODE ------------------- A B C A-B A-C B-A B-C C-A C-B A-B-C A-C-B B-A-C B-C-A C-A-B C-B-A 15 rows selected.
- 강좌 URL : http://www.gurubee.net/lecture/2681
- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.