[Oracle] With Clause (with as) 사용 방법 예제 자료

With Clause(with as)

with절은 인라인뷰 또는 임시테이블 역할을 수행할 수 있는 기능을 제공합니다.

특히 사용을 고려할만한 곳은 반복되는 서브쿼리 구문이 많은 뷰입니다.

예를 들면 EMP 테이블과 DEPT 테이블을 조인한 결과를 여러번 사용한다고 가정했을 때입니다. 다음과 같은 예제를 보여드리겠습니다.

WITH AS 예시 테이블

with 절 없이 예시 자료를 union all로 구현한다면 다음과 같을 것입니다.

뷰의 중복을 확인하실 수 있습니다.

SELECT EMPNO,
       ENAME,
       JOB,
       EMP.DEPTNO,
       DNAME,
       LOC
  FROM EMP JOIN DEPT ON DEPT.DEPTNO = EMP.DEPTNO AND EMP.DEPTNO = '10'
UNION ALL
SELECT EMPNO,
       ENAME,
       JOB,
       EMP.DEPTNO,
       DNAME,
       LOC
  FROM EMP JOIN DEPT ON DEPT.DEPTNO = EMP.DEPTNO AND LOC = 'CHICAGO'
UNION ALL
SELECT EMPNO,
       ENAME,
       JOB,
       EMP.DEPTNO,
       DNAME,
       LOC
  FROM EMP JOIN DEPT ON DEPT.DEPTNO = EMP.DEPTNO AND DNAME = 'RESEARCH';
  
       EMPNO ENAME                JOB                    DEPTNO DNAME                        LOC
---------- -------------------- ------------------ ---------- ---------------------------- --------------------------
      7782 CLARK                MANAGER                    10 ACCOUNTING                   NEW YORK
      7934 MILLER               CLERK                      10 ACCOUNTING                   NEW YORK
      7839 KING                 PRESIDENT                  10 ACCOUNTING                   NEW YORK
      7698 BLAKE                MANAGER                    30 SALES                        CHICAGO
      7566 JONES                MANAGER                    20 RESEARCH                     DALLAS
      7788 SCOTT                ANALYST                    20 RESEARCH                     DALLAS
      7902 FORD                 ANALYST                    20 RESEARCH                     DALLAS
      7369 SMITH                CLERK                      20 RESEARCH                     DALLAS
      7499 ALLEN                SALESMAN                   30 SALES                        CHICAGO
      7521 WARD                 SALESMAN                   30 SALES                        CHICAGO
      7654 MARTIN               SALESMAN                   30 SALES                        CHICAGO
      7844 TURNER               SALESMAN                   30 SALES                        CHICAGO
      7876 ADAMS                CLERK                      20 RESEARCH                     DALLAS
      7900 JAMES                CLERK                      30 SALES                        CHICAGO

14 rows selected.

중복되는 뷰를 WITH AS로 다음과 같이 통합할 수 있습니다.

WITH TAB
     AS (SELECT EMPNO,
                ENAME,
                JOB,
                EMP.DEPTNO,
                DNAME,
                LOC
           FROM EMP JOIN DEPT ON DEPT.DEPTNO = EMP.DEPTNO)
SELECT *
  FROM TAB
 WHERE DEPTNO = '10'
UNION ALL
SELECT *
  FROM TAB
 WHERE LOC = 'CHICAGO'
UNION ALL
SELECT *
  FROM TAB
 WHERE DNAME = 'RESEARCH';

     EMPNO ENAME                JOB                    DEPTNO DNAME                        LOC
---------- -------------------- ------------------ ---------- ---------------------------- --------------------------
      7934 MILLER               CLERK                      10 ACCOUNTING                   NEW YORK
      7839 KING                 PRESIDENT                  10 ACCOUNTING                   NEW YORK
      7782 CLARK                MANAGER                    10 ACCOUNTING                   NEW YORK
      7900 JAMES                CLERK                      30 SALES                        CHICAGO
      7844 TURNER               SALESMAN                   30 SALES                        CHICAGO
      7654 MARTIN               SALESMAN                   30 SALES                        CHICAGO
      7521 WARD                 SALESMAN                   30 SALES                        CHICAGO
      7698 BLAKE                MANAGER                    30 SALES                        CHICAGO
      7499 ALLEN                SALESMAN                   30 SALES                        CHICAGO
      7902 FORD                 ANALYST                    20 RESEARCH                     DALLAS
      7876 ADAMS                CLERK                      20 RESEARCH                     DALLAS
      7788 SCOTT                ANALYST                    20 RESEARCH                     DALLAS
      7566 JONES                MANAGER                    20 RESEARCH                     DALLAS
      7369 SMITH                CLERK                      20 RESEARCH                     DALLAS

14 rows selected.

with as 에서 뷰를 단수로 사용한다면 다음과 같이 사용합니다.

WITH TA AS (SELECT * FROM EMP)
SELECT *
  FROM TA;

     EMPNO ENAME                JOB                       MGR HIREDATE        SAL       COMM     DEPTNO
---------- -------------------- ------------------ ---------- -------- ---------- ---------- ----------
      7698 BLAKE                MANAGER                  7839 91/01/05       2850                    30
      7782 CLARK                MANAGER                  7839 99/09/06       2450                    10
      7566 JONES                MANAGER                  7839 01/02/04       2975                    20
      7788 SCOTT                ANALYST                  7566 03/06/17       3000                    20
      7902 FORD                 ANALYST                  7566 81/03/12       3000                    20
      7369 SMITH                CLERK                    7902 07/12/01        800                    20
      7499 ALLEN                SALESMAN                 7698 81/02/20       1600        300         30
      7521 WARD                 SALESMAN                 7698 81/02/22       1250        500         30
      7654 MARTIN               SALESMAN                 7698 81/09/28       1250       1400         30
      7844 TURNER               SALESMAN                 7698 81/08/09       1500          0         30
      7876 ADAMS                CLERK                    7788 87/05/23       1100                    20
      7900 JAMES                CLERK                    7698 81/03/12        950                    30
      7934 MILLER               CLERK                    7782 03/01/23       1300                    10
      7839 KING                 PRESIDENT                     96/11/17       5000                    10

14 rows selected.

WITH AS 여러개 사용 방법

with as 에서 뷰를 복수로 사용하면 콤마(,)로 구분하시면 됩니다.

WITH TA AS (SELECT * FROM EMP),
     TB AS (SELECT * FROM DEPT)
SELECT *
  FROM TA LEFT JOIN TB ON TB.DEPTNO = TA.DEPTNO;

     EMPNO ENAME                JOB                       MGR HIREDATE        SAL       COMM     DEPTNO     DEPTNO DNAMLOC
---------- -------------------- ------------------ ---------- -------- ---------- ---------- ---------- ---------- ---------------------------- --------------------------
      7839 KING                 PRESIDENT                     96/11/17       5000                    10         10 ACCOUNTING                   NEW YORK
      7934 MILLER               CLERK                    7782 03/01/23       1300                    10         10 ACCOUNTING                   NEW YORK
      7782 CLARK                MANAGER                  7839 99/09/06       2450                    10         10 ACCOUNTING                   NEW YORK
      7876 ADAMS                CLERK                    7788 87/05/23       1100                    20         20 RESEARCH                     DALLAS
      7369 SMITH                CLERK                    7902 07/12/01        800                    20         20 RESEARCH                     DALLAS
      7902 FORD                 ANALYST                  7566 81/03/12       3000                    20         20 RESEARCH                     DALLAS
      7788 SCOTT                ANALYST                  7566 03/06/17       3000                    20         20 RESEARCH                     DALLAS
      7566 JONES                MANAGER                  7839 01/02/04       2975                    20         20 RESEARCH                     DALLAS
      7900 JAMES                CLERK                    7698 81/03/12        950                    30         30 SALECHICAGO
      7844 TURNER               SALESMAN                 7698 81/08/09       1500          0         30         30 SALECHICAGO
      7654 MARTIN               SALESMAN                 7698 81/09/28       1250       1400         30         30 SALECHICAGO
      7521 WARD                 SALESMAN                 7698 81/02/22       1250        500         30         30 SALECHICAGO
      7499 ALLEN                SALESMAN                 7698 81/02/20       1600        300         30         30 SALECHICAGO
      7698 BLAKE                MANAGER                  7839 91/01/05       2850                    30         30 SALECHICAGO

14 rows selected.

다음은 오라클 테스트 테이블(demobld.sq)을 with as로 조회해 보는 예시입니다.

WITH EMP
     AS (SELECT 7369 EMPNO, 'SMITH' ENAME, 'CLERK' JOB, 7902 MGR, TO_DATE ('19801217') HIREDATE, 800 SAL, NULL COMM, 20 DEPTNO FROM DUAL UNION ALL
         SELECT 7499, 'ALLEN', 'SALESMAN', 7698, TO_DATE ('19810220'), 1600, 300, 30 FROM DUAL UNION ALL
         SELECT 7521, 'WARD', 'SALESMAN', 7698, TO_DATE ('19810222'), 1250, 500, 30 FROM DUAL UNION ALL
         SELECT 7566, 'JONES', 'MANAGER', 7839, TO_DATE ('19810402'), 2975, NULL, 20 FROM DUAL UNION ALL
         SELECT 7654, 'MARTIN', 'SALESMAN', 7698, TO_DATE ('19810928'), 1250, 1400, 30 FROM DUAL UNION ALL
         SELECT 7698, 'BLAKE', 'MANAGER', 7839, TO_DATE ('19810501'), 2850, NULL, 30 FROM DUAL UNION ALL
         SELECT 7782, 'CLARK', 'MANAGER', 7839, TO_DATE ('19810609'), 2450, NULL, 10 FROM DUAL UNION ALL
         SELECT 7788, 'SCOTT', 'ANALYST', 7566, TO_DATE ('19821209'), 3000, NULL, 20 FROM DUAL UNION ALL
         SELECT 7839, 'KING', 'PRESIDENT', NULL, TO_DATE ('19811117'), 5000, NULL, 10 FROM DUAL UNION ALL
         SELECT 7844, 'TURNER', 'SALESMAN', 7698, TO_DATE ('19810908'), 1500, 0, 30 FROM DUAL UNION ALL
         SELECT 7876, 'ADAMS', 'CLERK', 7788, TO_DATE ('19830112'), 1100, NULL, 20 FROM DUAL UNION ALL
         SELECT 7900, 'JAMES', 'CLERK', 7698, TO_DATE ('19811203'), 950, NULL, 30 FROM DUAL UNION ALL
         SELECT 7902, 'FORD', 'ANALYST', 7566, TO_DATE ('19811203'), 3000, NULL, 20 FROM DUAL UNION ALL
         SELECT 7934, 'MILLER', 'CLERK', 7782, TO_DATE ('19820123'), 1300, NULL, 10 FROM DUAL),
     DEPT
     AS (SELECT 10 DEPTNO, 'ACCOUNTING' DNAME, 'NEW YORK' LOC FROM DUAL UNION ALL
         SELECT 20, 'RESEARCH', 'DALLAS' FROM DUAL UNION ALL
         SELECT 30, 'SALES', 'CHICAGO' FROM DUAL UNION ALL
         SELECT 40, 'OPERATIONS', 'BOSTON' FROM DUAL),
     SALGRADE
     AS (SELECT 1 GRADE, 700 LOSAL, 1200 HISAL FROM DUAL UNION ALL
         SELECT 2, 1201, 1400 FROM DUAL UNION ALL
         SELECT 3, 1401, 2000 FROM DUAL UNION ALL
         SELECT 4, 2001, 3000 FROM DUAL UNION ALL
         SELECT 5, 3001, 9999 FROM DUAL)
SELECT * FROM EMP, DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO;

     EMPNO ENAME        JOB                       MGR HIREDATE        SAL       COMM     DEPTNO     DEPTNO DNAME                LOC
---------- ------------ ------------------ ---------- -------- ---------- ---------- ---------- ---------- -------------------- ----------------
      7369 SMITH        CLERK                    7902 80/12/17        800                    20         20 RESEARCH             DALLAS
      7499 ALLEN        SALESMAN                 7698 81/02/20       1600        300         30         30 SALES                CHICAGO
      7521 WARD         SALESMAN                 7698 81/02/22       1250        500         30         30 SALES                CHICAGO
      7566 JONES        MANAGER                  7839 81/04/02       2975                    20         20 RESEARCH             DALLAS
      7654 MARTIN       SALESMAN                 7698 81/09/28       1250       1400         30         30 SALES                CHICAGO
      7698 BLAKE        MANAGER                  7839 81/05/01       2850                    30         30 SALES                CHICAGO
      7782 CLARK        MANAGER                  7839 81/06/09       2450                    10         10 ACCOUNTING           NEW YORK
      7788 SCOTT        ANALYST                  7566 82/12/09       3000                    20         20 RESEARCH             DALLAS
      7839 KING         PRESIDENT                     81/11/17       5000                    10         10 ACCOUNTING           NEW YORK
      7844 TURNER       SALESMAN                 7698 81/09/08       1500          0         30         30 SALES                CHICAGO
      7876 ADAMS        CLERK                    7788 83/01/12       1100                    20         20 RESEARCH             DALLAS
      7900 JAMES        CLERK                    7698 81/12/03        950                    30         30 SALES                CHICAGO
      7902 FORD         ANALYST                  7566 81/12/03       3000                    20         20 RESEARCH             DALLAS
      7934 MILLER       CLERK                    7782 82/01/23       1300                    10         10 ACCOUNTING           NEW YORK

14 rows selected.

With As + Insert

INSERT INTO EMP (EMPNO, ENAME)
   WITH TAB AS (SELECT '9999', 'NAME' FROM DUAL)
   SELECT *
     FROM TAB;

with 절 다음에는 select 키워드가 따라와야 합니다. 그리하여 with as + update 는 대상 테이블의 컬럼을 지정하거나 뷰를 가공하여 활용합니다.

대신 insert 구문은 손쉽게 insert into [statement] with as 로 간단히 사용할 수 있습니다.

Oracle With As Example(EMP TABLE)

예제 생성 시 활용자료로 이용하려 만들어 보았습니다.

with as hint, /*+ MATERIALIZE */ /*+ INLINE */

가끔 볼수 수 있는 힌트입니다! materialize 힌트는 글로벌 템프 테이블을 만들라는 의미이고, inline 힌트는 인라인뷰에서 실행하라는 의미입니다. 오라클데이터베이스가 발전할수록 굳이 지정할 필요 없이, 알아서 퍼포먼스를 관리하기 때문에 별도로 지정하실 필요는 없어보입니다. 이러한 힌트도 있다는 것만 보고 넘어가시면 돼요.

WITH AS 를 SELECT 중간에 실행하기

WITH AS 절은 가독성을 위해 가장 먼저 배치하는 편이기는 한데, 경우에 따라 위치를 변경할 수도 있어요. 다음과 같이 할 수도 있습니다.

SELECT *
  FROM (WITH VW AS (SELECT * FROM EMP)
        SELECT DUAL.*, VW.*
          FROM DUAL LEFT JOIN VW ON 0 = 0);

DU      EMPNO ENAME                JOB                       MGR HIREDATE        SAL       COMM     DEPTNO
-- ---------- -------------------- ------------------ ---------- -------- ---------- ---------- ----------
X        7698 BLAKE                MANAGER                  7839 91/01/05       2850                    30
X        7782 CLARK                MANAGER                  7839 99/09/06       2450                    10
X        7566 JONES                MANAGER                  7839 01/02/04       2975                    20
X        7788 SCOTT                ANALYST                  7566 03/06/17       3000                    20
X        7902 FORD                 ANALYST                  7566 81/03/12       3000                    20
X        7369 SMITH                CLERK                    7902 07/12/01        800                    20
X        7499 ALLEN                SALESMAN                 7698 81/02/20       1600        300         30
X        7521 WARD                 SALESMAN                 7698 81/02/22       1250        500         30
X        7654 MARTIN               SALESMAN                 7698 81/09/28       1250       1400         30
X        7844 TURNER               SALESMAN                 7698 81/08/09       1500          0         30
X        7876 ADAMS                CLERK                    7788 87/05/23       1100                    20
X        7900 JAMES                CLERK                    7698 81/03/12        950                    30
X        7934 MILLER               CLERK                    7782 03/01/23       1300                    10
X        7839 KING                 PRESIDENT                     96/11/17       5000                    10

14 rows selected.

댓글