ROLLUP의 복제기술응용(1)

Updated:

ROLLUP의 복제기술(1)

rollup은 안시 sql99의 대표적인 함수로 거의 모든 DBMS에서 제공하고 있습니다. 이 함수에 1이라는 숫자를 넣어 복제를 만들어 사용할수 있습니다. 테이블에 1번만 접근하면서 여러번 테이블을 접근하는것과 같은 효과를 내어 SQL속도를 빠르게 할때 많이 사용하는 기술입니다.

아래의 SQL을 보면 1이라는 숫자가 ROLLUP의 맨앞에 나와 있습니다. 이때 1이라는 숫자가 어떤 역활을 하는걸까? 결론적으로 말하면 ROLLUP에 의해 생성되는 총계값을 한번 더 생성합니다. 원리를 살펴보면

ROLLUP( 1, 칼럼) 이런 표현은 다음과 같은 표현입니다.

ROLLUP(1, 칼럼) = GRUPING SETS ( ( 1, 칼럼),
                                ( 1 ),
                                (   )  )

여기에서 (1) 과 ( ) 은 동일한 표현입니다, 그래서 총계가 한번더 생성되는 것입니다.

union all로 표현하면

select ........
from ...
group by 1, 칼럼  <--(1, 칼럼)(칼럼) 과 동일합니다
union all
select ........
from ...
group by (1)
union all
select 
select ........
from ...
group by ( )  <-- 총계를 구하라는 뜻입니다.

가. ROLLUP에서 1을 이용한 복제해봅니다

TOTAL값을 추가복제하여 하나는 AVG(SAL)로 변경 처리합니다. 예제 SQL을 보면 맨 앞에 있는 1 로 인해 총계가 한번더 생성됩니다.

select deptno, job, ename, comm, sum(sal)   
 from emp
group by  rollup(1, (deptno, job, ename, comm));
DEPTNO JOB ENAME COMM SUM(SAL)
10 CLERK MILLER   1300
10 MANAGER CLARK   2450
10 PRESIDENT KING   5000
20 CLERK ADAMS   1100
20 CLERK SMITH   800
20 ANALYST FORD   3000
20 ANALYST SCOTT   1100
20 MANAGER JONES   2975
30 CLERK JAMES   950
30 MANAGER BLAKE   2850
30 SALESMAN WARD 500 1250
30 SALESMAN ALLEN 300 1600
30 SALESMAN MARTIN 1400 1250
30 SALESMAN TURNER 0 1500
        27125
        27125 –생성값

나. GROUPING함수를 이용하여 값 변경

GROUPING_ID 펑션을 사용하여 복제된 총합계를 AVG(SAL)값을 변경해봅니다.
이떄 GROUPING_ID(1, JOB) 를 사용하였으로 GB값이 0, 1, 3값이 생성됩니다. 이 코드값을 가지고 DECODE나 CASE를 사용하여 AVG(SAL)값으로 바꾸면 됩니다.

select deptno, job, ename, comm, 
         DECODE(GROUPING_ID(1,job), 3, AVG(SAL), SUM SAL)) AA, 
         GROUPING_ID(1,JOB) GB
from emp
group by  rollup(1, (deptno, job, ename, comm));
DEPTNO JOB ENAME COMM SUM(SAL) GB
10 CLERK MILLER   1300 0
10 MANAGER CLARK   2450 0
10 PRESIDENT KING   5000 0
20 CLERK ADAMS   1100 0
20 CLERK SMITH   800 0
20 ANALYST FORD   3000 0
20 ANALYST SCOTT   1100 0
20 MANAGER JONES   2975 0
30 CLERK JAMES   950 0
30 MANAGER BLAKE   2850 0
30 SALESMAN WARD 500 1250 0
30 SALESMAN ALLEN 300 1600 0
30 SALESMAN MARTIN 1400 1250 0
30 SALESMAN TURNER 0 1500 0
        27125 1
        1937.5 3

다. 서브 TOTAL값을 복제하여 AVG(SAL)로 변경 처리

이번에는 중간에 1이 하나더 들어갔습니다. 이때는 서브 TOTAL값이 하나더 생성됩니다. 즉 1을 몇개 더 넣으면 역시 넣은만큼 추가 복제가 이루어집니다.

ROLLUP(칼럼1, 1, 칼럼2)= GROUPING SETS((칼럼1,1,칼럼2)
                                       (칼럼1, 1),  
                                       (칼럼1),  
                                       () ) 

이때 (칼럼1, 1) 과 (칼럼1) 이 동일한 표현입니다, 그러므로 서브TOTAL이 1번더 복제됩니다.

select a.deptno, a.job, b.dname, b.loc, sum(sal) , grouping_id(a.deptno, 1, a.job)
from emp a, dept b   
where a.deptno=b.deptno
group by rollup(a.deptno, 1, (a.job, b.dname, b.loc))
order by a.deptno, a.job; 
A.DEPTNO A.JOB B.DNAME B.LOC SUM(SAL) AA
10 CLERK ACCOUNTING NEW YORK 1300 0
10 MANAGER ACCOUNTING NEW YORK 2450 0
10 PRESIDENT ACCOUNTING NEW YORK 5000 0
10       8750 1
10       8750 3
20 ANALYST RESEARCH DALLAS 4100 0
20 CLERK RESEARCH DALLAS 1900 0
20 MANAGER RESEARCH DALLAS 2975 0
20       8975 1
20       8975 3
30 CLERK SALES CHICAGO 950 0
30 MANAGER SALES CHICAGO 2850 0
30 SALESMAN SALES CHICAGO 5600 0
30       9400 1
30       9400 3
        27125 7

라. GROUPING_ID 함수를 이용하여 설명 추가

Grouping _id값을 이용하여 복제된 서브 토탈값을 원하는 값으로 변경 처리합니다.

SELECT A.DEPTNO,
         DECODE(GROUPING_ID(A.DEPTNO , 1 , A.JOB), 1 , A.DEPTNO||' : 합계',
                                                   3 , A.DEPTNO||' : 평균' ,
                                                   7 , ‘전부서 총합‘ , A.JOB) JOB, 
          B.DNAME,  B.LOC,
          DECODE(GROUPING_ID(A.DEPTNO,1,A.JOB), 3, TRUNC(AVG(SAL)), SUM(A.SAL)) SAL,
          GROUPING_ID(A.DEPTNO, 1, A.JOB) BB
FROM EMP A, DEPT B
WHERE A.DEPTNO=B.DEPTNO
GROUP BY ROLLUP(A.DEPTNO,1, (A.JOB,B.DNAME,B.LOC))
ORDER BY A.DEPTNO, BB, A.JOB;
A.DEPTNO A.JOB B.DNAME B.LOC SUM(SAL) AA
10 CLERK ACCOUNTING NEW YORK 1300 0
10 MANAGER ACCOUNTING NEW YORK 2450 0
10 PRESIDENT ACCOUNTING NEW YORK 5000 0
10 10 : 합계     8750 1
10 10 : 평균     2916 3
20 ANALYST RESEARCH DALLAS 4100 0
20 CLERK RESEARCH DALLAS 1900 0
20 MANAGER RESEARCH DALLAS 2975 0
20 20 :합계     8975 1
20 20 : 평균     1795 3
30 CLERK SALES CHICAGO 950 0
30 MANAGER SALES CHICAGO 2850 0
30 SALESMAN SALES CHICAGO 5600 0
30 30 : 합계     9400 1
30 30 : 평균     1566 3
  전부서총합     27125 7