혼자 공부하는 공간

[SQL기본 및 활용] 2020년 SQLD 내용 정리 :: SQL 활용 #5 본문

자격증/SQLD

[SQL기본 및 활용] 2020년 SQLD 내용 정리 :: SQL 활용 #5

god_z 2020. 8. 31. 14:53

<목차>


<< 그룹 함수 >>

* ANSI/ISO SQL 표준은 데이터 분석을 위해서 다음 세 가지 함수를 정의하고 있다.

  1. AGGREGATE FUNCTION

    • GROUP AGGREGATE FUNCTION 으로도 부르며, GROUP FUNCTION의 한 부분으로 분류된다.

    • COUNT, MIN, MAX, AVG, SUM 등 집계 함수들이 포함되어 있다.

  2. GROUP FUNCTION

    • 하나의 SQL로 테이블을 한 번만 읽어서 빠르게 원하는 리포트를 작성할 수 있도록 해주는 함수

    • 집계 함수를 제외한 ROLLUP, CUBE, GROUPING SETS 함수가 있다.

      * ROLLUP : 소그룹 간의 소계를 계산하는 함수이다. GROUP BY의 확장된 형태로 사용하며 병렬로 수행이 가능하기 때문에 매우 효과적.

       

      * CUBE : GROUP BY 항목들 간 다차원적인 소계를 계산할 수 있는 함수이다. 결합 가능한 모든 값에 대한 다차원적인 집계를 생성하게 되므로 ROLLUP에 비해 다양한 데이터를 얻을 수 있다. 하지만 시스템이 부하를 많이 주는 단점도 존재.

       

      * GROUPING SETS : 원하는 부분의 소계만 손쉽게 추출할 수 있다. (시스템에 주는 부하가 적음)

       

      ---> 정렬이 필요한 경우, ORDER BY 절에 정렬 칼럼을 명시한다.

  3. WINDOW FUNCTION

    • 분석 함수 또는 순위 함수.

 


 

1. ROLLUP 함수

* ROLLUP에 지정된 Grouping Columns의 리스트는 Sub Total을 생성하기 위해 사용되며, Grouping Columns의 수를 N이라고 했을 때, N+1 레벨의 Subtotal이 생성된다.

* ROLLUP의 인수는 계층 구조이므로 인수 순서가 바뀌면 수행 결과도 바뀐다.

* GROUP BY 절과 함께 사용된다.

 

 

A. 1단계 : 일반적인 GROUP BY 절 사용

* 예시 : 부서명(DNAME)과 업무명(JOB)을 기준으로 사원수와 급여 합을 집계한 일반적인 GROUP BY SQL 문장

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
SELECT D.DNAME, E.JOB, COUNT(*) AS "Total Empl", SUM(E.SAL) AS "Total Sal"
FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO
GROUP BY D.DNAME, E.JOB;
 
/*
DNAME      JOB      Total Empl Total Sal 
--------- --------- ---------- --------- 
SALES      MANAGER   1          2850 
SALES      CLERK     1          950 
ACCOUNTING MANAGER   1          2450 
RESEARCH   ANALYST   2          6000 
ACCOUNTING CLERK     1          1300 
SALES      SALESMAN  4          5600 
RESEARCH   MANAGER   1          2975 
ACCOUNTING PRESIDENT 1          5000 
RESEARCH   CLERK     2          1900 
9개의 행이 선택되었다.
*/
cs

---> 1단계의 결과에서 정렬이 필요하다.

 

 

B. 1-2 단계 : GROUP BY 절 + ORDER BY 절

* 예시 : 부서명(DNAME)과 업무명(JOB)을 기준으로 사원수와 급여 합을 집계한 일반적인 GROUP BY SQL 문장에 부서명, 업무명 기준으로 오름차순 정렬하라.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
SELECT D.DNAME, E.JOB, COUNT(*) AS "Total Empl", SUM(E.SAL) AS "Total Sal"
FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO
GROUP BY D.DNAME, E.JOB
ORDER BY D.DNAME, E.JOB;
 
/*
DNAME      JOB      Total Empl Total Sal 
--------- --------- ---------- --------- 
ACCOUNTING CLERK     1          1300 
ACCOUNTING MANAGER   1          2450 
ACCOUNTING PRESIDENT 1          5000 
RESEARCH   ANALYST   2          6000 
RESEARCH   CLERK     2          1900 
RESEARCH   MANAGER   1          2975 
SALES      CLERK     1          950 
SALES      MANAGER   1          2850 
SALES      SALESMAN  4          5600 
9개의 행이 선택되었다.
*/
cs

---> ROLLUP을 통해 각 소그룹(DNAME, JOB)별로 소계를 구할 수 있다.

 

 

C. 2단계 : ROLLUP 함수 사용

* 예시 : 부서명(DNAME)과 업무명(JOB)을 기준으로 사원수와 급여 합을 집계한 일반적인 GROUP BY SQL 문장에 ROLLUP 함수를 사용한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
SELECT D.DNAME, E.JOB, COUNT(*"Total Empl", SUM(E.SAL) "Total Sal" 
FROM EMP E, DEPT D
WHERE D.DEPTNO = E.DEPTNO 
GROUP BY ROLLUP (D.DNAME, E.JOB);
 
/*
DNAME      JOB      Total Empl Total Sal 
---------- --------- ---------- --------- 
SALES      CLERK     1          950 
SALES      MANAGER   1          2850 
SALES      SALESMAN  4          5600 
SALES                6          9400 
RESEARCH   CLERK     2          1900 
RESEARCH   ANALYST   2          6000 
RESEARCH   MANAGER   1          2975 
RESEARCH             5          10875 
ACCOUNTING CLERK     1          1300 
ACCOUNTING MANAGER   1          2450 
ACCOUNTING PRESIDENT 1          5000 
ACCOUNTING           3          8750 
                     14         29025 
13개의 행이 선택되었다.
*/
cs

---> 1단계와의 결과를 비교해보면 결과 행에서 차이점이 존재한다.

     L1 : GROUP BY 수행 시 생성되는 표준 집계 (9건)

        - 1단계 결과를 말한다.

     L2 : DNAME 별 모든 JOB의 Sub Total (3건)

        - 부서명 별 데이터의 소계에 해당하는 데이터 (JOB = NULL) 인 데이터

     L3 : GRAND TOTAL (1건)

        - 부서명 별/업무명 별 총계에 해당하는 데이터 (가장 최하단의 데이터)

        - 마지막 (DNAME, JOB) = (NULL, NULL)인 데이터를 말한다.

---> 추가로 ROLLUP함수의 경우 계층 간 집계에 대해서는 레벨 별 순서(L1 - L2 - L3)를 정렬하지만, 계층 내 GROUP BY 수행 시 생성되는 표준 집계에서는 별도의 정렬을 지원하지 않는다. (ORDER BY 절을 사용해야 한다.)

 

 

D. 2-2 단계 : ROLLUP 함수 + ORDER BY 절 사용

* 예시 : 부서명(DNAME)과 업무명(JOB)을 기준으로 사원수와 급여 합을 집계한 일반적인 GROUP BY SQL 문장에 ROLLUP 함수를 사용한다. 추가로 ORDER BY 절을 사용해서 부서명, 업무명 기준으로 정렬하라.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
SELECT D.DNAME, E.JOB, COUNT(*"Total Empl", SUM(E.SAL) "Total Sal" 
FROM EMP E, DEPT D
WHERE D.DEPTNO = E.DEPTNO 
GROUP BY ROLLUP (D.DNAME, E.JOB)
ORDER BY D.DNAME, E.JOB ;
 
/*
DNAME        JOB       Total Empl  Total Sal 
------------ --------- ----------- ---------- 
ACCOUNTING   CLERK     1           1300 
ACCOUNTING   MANAGER   1           2450 
ACCOUNTING   PRESIDENT 1           5000 
ACCOUNTING             3           8750 
RESEARCH     ANALYST   2           6000   
RESEARCH     CLERK     2           1900 
RESEARCH     MANAGER   1           2975 
RESEARCH               5           10875 
SALES        CLERK     1           950 
SALES        MANAGER   1           2850 
SALES        SALESMAN  4           5600 
SALES                  6           9400 
                       14          29025 
13개의 행이 선택되었다.
*/
cs

 

 

E. 3단계 : GROUPING 함수 사용

* ROLLUP, CUBE, GROUPING SETS 등 새로운 그룹 함수를 지원하기 위해 GROUPING 함수가 추가되었다.

   - ROLLUP/CUBE에 의한 소계가 계산된 결과에는 GROUPING(EXPR) = 1 표시

   - 그 외의 결과에는 GROUPING(EXPR) = 0 표시

* GROUPING 함수와 CASE/DECODE를 이용해서 소계를 나타내는 필드에 원하는 문자열을 지정할 수 있어, 보고서 작성시 유용하게 사용할 수 있다.

 

* 예시 : ROLLUP 함수를 추가한 집계 보고서에서 집계 레코드를 구분할 수 있는 GROUPING 함수가 추가된 SQL 문장이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
SELECT D.DNAME, GROUPING(D.DNAME), E.JOB, GROUPING(E.JOB), COUNT(*"Total Empl", SUM(E.SAL) "Total Sal" 
FROM EMP E, DEPT D
WHERE D.DEPTNO = E.DEPTNO 
GROUP BY ROLLUP (D.DNAME, E.JOB);
 
/*
DNAME      GROUPING(DNAME) JOB        GROUPING(JOB)  Total Empl  Total Sal
---------- --------------  ---------  -------------  ----------- --------- 
SALES      0               CLERK      0              1           950 
SALES      0               MANAGER    0              1           2850 
SALES      0               SALESMAN   0              4           5600 
SALES      0                          1              6           9400 
RESEARCH   0               CLERK      0              2           1900 
RESEARCH   0               ANALYST    0              2           6000 
RESEARCH   0               MANAGER    0              1           2975 
RESEARCH   0                          1              5           10875 
ACCOUNTING 0               CLERK      0              1           1300 
ACCOUNTING 0               MANAGER    0              1           2450 
ACCOUNTING 0               PRESIDENT  0              1           5000 
ACCOUNTING 0                          1              3           8750 
           1                          1              14          29025 
13개의 행이 선택되었다.
*/
cs

---> 부서명 별, 업무명 별과 전체 집계를 표시한 레코드에서는 GROUPING 함수가 1을 반환했다.

---> 전체 합계를 나타내는 마지막 레코드에서는 부서명 별 GROUPING 함수와 업무명 별 GROUPING 함수가 모두 1이다. (부서명 별 소계이자 업무명 별 소계이기 때문에)

 

 

F. 4단계 : GROUPING 함수 + CASE 사용

* 예시 : ROLLUP 함수를 추가한 집계 보고서에서 집계 레코드를 구분할 수 있는 GROUPING 함수와 CASE 함수와 함께 사용한 SQL 문 작성.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
SELECT 
    CASE GROUPING(D.DNAME) 
        WHEN 1 
        THEN 'All Departments' 
        ELSE D.DNAME 
    END AS DNAME, 
        CASE GROUPING(E.JOB) 
        WHEN 1 
        THEN 'All Jobs' 
        ELSE E.JOB 
    END AS JOB, 
    COUNT(*"Total Empl", SUM(SAL) "Total Sal" 
FROM EMP E, DEPT D
WHERE D.DEPTNO = E.DEPTNO 
GROUP BY ROLLUP (D.DNAME, E.JOB); 
 
 
/* Oracle 에서는 DECODE로 사용할 수도 있다. */
SELECT 
    DECODE(GROUPING(D.DNAME), 1'All Departments', D.DNAME) AS DNAME,
    DECODE(GROUPING(E.JOB), 1'All Jobs', E.JOB) AS JOB,
    COUNT(*"Total Empl"
   SUM(E.SAL) "Total Sal" 
FROM EMP E, DEPT D
WHERE D.DEPTNO = E.DEPTNO 
GROUP BY ROLLUP (D.DNAME, E.JOB); 
 
/*
DNAME             JOB      Total Empl  Total Sal 
----------------- -------- ----------- -------- 
SALES             CLERK     1          950  
SALES             MANAGER   1          2850 
SALES             SALESMAN  4          5600 
SALES             All Jobs  6          9400 
RESEARCH          CLERK     2          1900 
RESEARCH          ANALYST   2          6000 
RESEARCH          MANAGER   1          2975 
RESEARCH          All Jobs  5          10875 
ACCOUNTING        CLERK     1          1300 
ACCOUNTING        MANAGER   1          2450 
ACCOUNTING        PRESIDENT 1          5000 
ACCOUNTING        All Jobs  3          8750 
All Departments   All Jobs  14         29025 
13개의 행이 선택되었다.
*/
cs

---> 업무명 별 소계를 표시한 레코드에는 'All Jobs', 부서명 별 소계를 표시한 레코드에는 'All Departments' 라는 사용자 정의 텍스트로 설정했다.

 

 

G. 4-2단계 : ROLLUP 함수 일부 사용

* 예시 : GROUP BY ROLLUP (DNAME, JOB) 조건에서 GROUP BY DNAME, ROLLUP(JOB) 조건으로 변경한 경우.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
SELECT 
    CASE GROUPING(D.DNAME) 
        WHEN 1 
        THEN 'All Departments' 
        ELSE D.DNAME 
    END AS DNAME, 
    CASE GROUPING(E.JOB) 
        WHEN 1 
        THEN 'All Jobs' 
        ELSE E.JOB 
    END AS JOB, 
    COUNT(*"Total Empl"
    SUM(E.SAL) "Total Sal" 
FROM EMP E, DEPT D
WHERE D.DEPTNO = E.DEPTNO 
GROUP BY D.DNAME, ROLLUP(E.JOB);
 
/* 
    F번의 예시와 마찬가지로 Oracle에서는 CASE 대신
    DECODE(GROUPING(D.DNAME), 1, 'All Departments', D.DNAME) AS DNAME
    으로 표현 가능
*/
 
/*
DNAME             JOB       Total Empl  Total Sal 
----------------- --------- ----------- -------- 
SALES             CLERK     1           950 
SALES             MANAGER   1           2850 
SALES             SALESMAN  4           5600 
SALES             All Jobs  6           9400 
RESEARCH          CLERK     2           1900 
RESEARCH          ANALYST   2           6000 
RESEARCH          MANAGER   1           2975 
RESEARCH          All Jobs  5           10875 
ACCOUNTING        CLERK     1           1300 
ACCOUNTING        MANAGER   1           2450 
ACCOUNTING        PRESIDENT 1           5000 
ACCOUNTING        All Jobs  3           8750  
12개의 행이 선택되었다.
*/
cs

 

---> ROLLUP 함수가 JOB 칼럼에만 사용되었기 때문에 DNAME 칼럼에 대한 총 집계는 출력되지 않았다.

 

 

H. 4-3단계 : ROLLUP 함수 결합 칼럼 사용

* 예시 : JOB과 MGR은 하나의 집합으로 간주하고, 부서명 별 JOB & MGR에 대한 ROLLUP 결과를 출력.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
SELECT D.DNAME, E.JOB, E.MGR, SUM(E.SAL) "Total Sal" 
FROM EMP E, DEPT D
WHERE D.DEPTNO = E.DEPTNO 
GROUP BY ROLLUP (D.DNAME, (E.JOB, E.MGR));
 
/*
DNAME       JOB       MGR  Total Sal 
----------- --------- ---- --------- 
SALES       CLERK     7698 950 
SALES       MANAGER   7839 2850 
SALES       SALESMAN  7698 5600 
SALES                      9400 
RESEARCH    CLERK     7788 1100 
RESEARCH    CLERK     7902 800 
RESEARCH    ANALYST   7566 6000 
RESEARCH    MANAGER   7839 2975 
RESEARCH                   10875 
ACCOUNTING  CLERK     7782 1300 
ACCOUNTING  MANAGER   7839 2450 
ACCOUNTING  PRESIDENT      5000 
ACCOUNTING             8750
29025
14개의 행이 선택되었다.
*/
cs

---> ROLLUP 함수 사용 시, 괄호로 묶은 JOB, MGR의 경우 하나의 집합 칼럼으로 간주하여 괄호 내 각 칼럼별 소계를 구하지 않는다.

 

2. CUBE 함수

* ROLLUP에서는 단지 가능한 Sub Total만을 생성하였지만, CUBE는 결합 가능한 모든 값에 대해 다차원 집계를 생성한다.

* Grouping Columns가 가질 수 있는 모든 경우에 대해 Sub Total을 생성해야 하는 경우 CUBE를 사용하는 것이 바람직하지만, ROLLUP에 비해 시스템에 많은 부담을 주기 때문에 사용에 주의하도록 한다.

* ROLLUP과 같이 인수들에 대한 계층별 집계를 구할 수 있다. 하지만 계층 구조인 ROLLUP과는 달리 평등한 관계이므로 인수의 순서가 바뀌어도 결과는 동일하다.

* ROLLUP과 같이 정렬이 필요한 경우 ORDER BY 절에 명시적으로 칼럼을 표시해야 하며, GROUP BY 절과 함께 사용된다.

 

 

I. 5단계 : CUBE 함수 이용

* 예시 : GROUP BY ROLLUP (D.DNAME, E.JOB) 조건에서 GROUP BY CUBE (D.DNAME, JOB) 조건으로 변경해서 수행해본다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
SELECT 
    CASE GROUPING(D.DNAME) 
        WHEN 1 
        THEN 'All Departments' 
        ELSE D.DNAME 
    END AS DNAME, 
    CASE GROUPING(E.JOB) 
        WHEN 1 
        THEN 'All Jobs' 
        ELSE E.JOB 
    END AS JOB, 
    COUNT(*"Total Empl"
    SUM(E.SAL) "Total Sal" 
FROM EMP E, DEPT D
WHERE D.DEPTNO = E.DEPTNO 
GROUP BY CUBE (D.DNAME, E.JOB) ;
 
/*
DNAME            JOB       Total Empl Total Sal 
---------------- --------- ---------- ---------- 
All Departments  All Jobs   14        29025 
All Departments  CLERK      4         4150 
All Departments  ANALYST    2         6000 
All Departments  MANAGER    3         8275  
All Departments  SALESMAN   4         5600 
All Departments  PRESIDENT  1         5000 
SALES            All Jobs   6         9400 
SALES            CLERK      1         950 
SALES            MANAGER    1         2850 
SALES            SALESMAN   4         5600 
RESEARCH         All Jobs   5         10875 
RESEARCH         CLERK      2         1900 
RESEARCH         ANALYST    2         6000 
RESEARCH         MANAGER    1         2975 
ACCOUNTING       All Jobs   3         8750 
ACCOUNTING       CLERK      1         1300 
ACCOUNTING       MANAGER    1         2450 
ACCOUNTING       PRESIDENT  1         5000 
18개의 행이 선택되었다.
*/
cs

---> CUBE는 Grouping Columns가 가질 수 있는 모든 경우의 수에 대해 Sub Total을 생성하기 때문에 Grouping Columns의 수가 N이라고 하면 2^N 레벨의 Sub Total을 생성한다.

 

---> 결과를 보면 ROLLUP 결과에 업무명 별 집계까지 추가해서 출력되었다. (line22 - line26)

 

 

J. 5-2단계 : UNION ALL 사용

* UNION ALL 은 집합 연산자이며 여러 SQL 문장을 연결하는 역할을 한다.

 

* 예시 : UNION ALL을 사용하여 5단계의 예시의 결과와 동일하게 출력할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
SELECT DNAME, JOB, COUNT(*"Total Empl", SUM(SAL) "Total Sal" 
FROM EMP, DEPT 
WHERE DEPT.DEPTNO = EMP.DEPTNO 
GROUP BY DNAME, JOB 
UNION ALL 
SELECT DNAME, 'All Jobs', COUNT(*"Total Empl", SUM(SAL) "Total Sal" 
FROM EMP, DEPT 
WHERE DEPT.DEPTNO = EMP.DEPTNO 
GROUP BY DNAME 
UNION ALL 
SELECT 'All Departments', JOB, COUNT(*"Total Empl", SUM(SAL) "Total Sal" 
FROM EMP, DEPT 
WHERE DEPT.DEPTNO = EMP.DEPTNO 
GROUP BY JOB 
UNION ALL 
SELECT 'All Departments''All Jobs', COUNT(*"Total Empl", SUM(SAL) "Total Sal" 
FROM EMP, DEPT 
WHERE DEPT.DEPTNO = EMP.DEPTNO ;
cs

---> SQL문 4개를 UNION ALL하기 때문에 코드의 길이가 굉장히 길고, 기존의 같은 테이블을 4번이나 액세스한다.

 

---> CUBE 함수 사용으로 코드의 길이가 짧아져 가독성이 좋아지고, 4번의 액세스에서 단 한 번의 액세스로 구현할 수 있게 되었다.

 

3. GROUPING SETS 함수

* GROUPING SETS를 통해 더욱 다양한 소계 집합을 만들 수 있는데, GROUP BY 절을 여러 번 반복하지 않아도 원하는 결과를 얻을 수 있다.

* GROUPING SETS의 인수들에 대한 개별 집계를 구할 수 있으며, 이 때 표시된 인수들 간에는 계층 구조인 ROLLUP과는 달리 평등한 관계이므로(CUBE와 같은) 인수 순서에 관계 없이 결과는 같다.

* ROLLUP, CUBE와 같이 정렬이 필요한 경우 ORDER BY 절에 명시적으로 칼럼을 표시해야 하며, GROUP BY 절과 함께 사용된다.

 

* 예시 - 문제 (일반 그룹함수 사용)

   : 부서별, JOB별 인원수와 급여의 합을 구하라.

 

* 예시 - 결과

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
SELECT DNAME, 'All Jobs' JOB, COUNT(*"Total Empl", SUM(SAL) "Total Sal" 
FROM EMP, DEPT 
WHERE DEPT.DEPTNO = EMP.DEPTNO 
GROUP BY DNAME 
UNION ALL 
SELECT 'All Departments' DNAME, JOB, COUNT(*"Total Empl", SUM(SAL) "Total Sal" 
FROM EMP, DEPT 
WHERE DEPT.DEPTNO = EMP.DEPTNO 
GROUP BY JOB ;
 
/*
DNAME           JOB       Total Empl Total Sal 
--------------- --------- ---------- ----------
ACCOUNTING      All Jobs  3          8750 
RESEARCH        All Jobs  5          10875 
SALES           All Jobs  6          9400 
All Departments CLERK     4          4150 
All Departments SALESMAN  4          5600 
All Departments PRESIDENT 1          5000 
All Departments MANAGER   3          8275 
All Departments ANALYST   2          6000 
8개의 행이 선택되었다.
*/
cs

 

* 예시 - 문제 (GROUPING SETS 함수 사용)

   : 부서별, JOB별 인원수와 급여의 합을 구하라.

 

* 예시 - 결과

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
SELECT 
    DECODE(GROUPING(DNAME), 1'All Departments', DNAME) AS DNAME, 
    DECODE(GROUPING(JOB), 1'All Jobs', JOB) AS JOB, 
    COUNT(*"Total Empl"
    SUM(SAL) "Total Sal" 
FROM EMP, DEPT 
WHERE DEPT.DEPTNO = EMP.DEPTNO 
GROUP BY GROUPING SETS (DNAME, JOB);
 
/*
DNAME           JOB       Total Empl Total Sal 
--------------- --------- ---------- ----------
All Departments CLERK     4          4150 
All Departments SALESMAN  4          5600 
All Departments PRESIDENT 1          5000 
All Departments MANAGER   3          8275 
All Departments ANALYST   2          6000 
ACCOUNTING      All Jobs  3          8750 
RESEARCH        All Jobs  5          10875 
SALES           All Jobs  6          9400 
8개의 행이 선택되었다.
*/
cs

---> GROUPING SETS의 인수인 DNAME, JOB의 순서가 바뀌어도 결과는 같다.

 

* 예시 - 문제 (GROUPING SETS 3개의 인수)

   : 부서 - JOB - 매니저 별 집계와 부서 - JOB 별 집계, JOB - 매니저 별 집계를 GROUPING SETS 함수를 이용해서 구해본다.

 

* 예시 - 결과

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
SELECT DNAME, JOB, MGR, SUM(SAL) "Total Sal" 
FROM EMP, DEPT 
WHERE DEPT.DEPTNO = EMP.DEPTNO 
GROUP BY GROUPING SETS ((DNAME, JOB, MGR), (DNAME, JOB), (JOB, MGR));
 
/*
DNAME       JOB        MGR     Total Sal 
----------- ---------- ------- --------- 
SALES       CLERK      7698    950 
ACCOUNTING  CLERK      7782    1300 
RESEARCH    CLERK      7788    1100 
RESEARCH    CLERK      7902    800 
RESEARCH    ANALYST    7566    6000 
SALES       MANAGER    7839    2850 
RESEARCH    MANAGER    7839    2975 
ACCOUNTING  MANAGER    7839    2450 
SALES       SALESMAN   7698    5600 
ACCOUNTING  PRESIDENT          5000   
            CLERK      7698    950 
            CLERK      7782    1300 
            CLERK      7788    1100 
            CLERK      7902    800 
            ANALYST    7566    6000 
            MANAGER    7839    8275 
            SALESMAN   7698    5600 
            PRESIDENT          5000  
SALES       MANAGER            2850 
SALES       CLERK              950 
ACCOUNTING  CLERK              1300 
ACCOUNTING  MANAGER            2450 
ACCOUNTING  PRESIDENT          5000 
RESEARCH    MANAGER            2975 
SALES       SALESMAN           5600 
RESEARCH    ANALYST            6000 
RESEARCH    CLERK              1900 
27개의 행이 선택되었다.
*/
cs

---> line9 - line18 (10건) : 부서-JOB-매니저 별 집계

---> line19 - line26 (8건) : JOB-매니저 별 집계

---> line27 - line35 (9건) : 부서-JOB 별 집계

 

 

 

 

출처

www.dbguide.net/db.db?cmd=view&boardUid=148204&boardConfigUid=9&categoryUid=216&boardIdx=135&boardStep=1

 

데이터 전문가 지식포털 DBGuide.net

표준 조인 집합 연산자 계층형 질의와 셀프 조인 서브쿼리 그룹 함수 윈도우 함수 DCL 절차형 SQL 1. 데이터 분석 개요 ANSI/ISO SQL 표준은 데이터 분석을 위해서 다음 세 가지 함수를 정의하고 있다.

www.dbguide.net

 

Comments