Useful Information
SELECT DNAME, JOB, COUNT(*) "Total Empl", SUM(SAL) "Total Sal"
FROM EMP, DEPT
WHERE DEPT.DEPTNO = EMP.DEPTNO
GROUP BY DNAME, JOB;
DNAME JOB Total Empl Total Sal
-------------- --------- ---------- ----------
SALES MANAGER 1 2850
SALES CLERK 1 950
ACCOUNTING MANAGER 1 2450
ACCOUNTING PRESIDENT 1 5000
ACCOUNTING CLERK 1 1300
SALES SALESMAN 4 5600
RESEARCH MANAGER 1 2975
RESEARCH ANALYST 2 6000
RESEARCH CLERK 2 1900
9 rows selected.
SELECT DNAME, JOB, COUNT(*) "Total Empl", SUM(SAL) "Total Sal"
FROM EMP, DEPT
WHERE DEPT.DEPTNO = EMP.DEPTNO
GROUP BY DNAME, JOB ORDER BY DNAME, 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 rows selected.
SELECT DNAME, JOB, COUNT(*) "Total Empl", SUM(SAL) "Total Sal"
FROM EMP, DEPT
WHERE DEPT.DEPTNO = EMP.DEPTNO
GROUP BY ROLLUP (DNAME, JOB);
DNAME JOB Total Empl Total Sal
-------------- --------- ---------- ----------
SALES CLERK 1 950 Level 1
SALES MANAGER 1 2850
SALES SALESMAN 4 5600
SALES 6 9400 > Level 2
RESEARCH CLERK 2 1900
RESEARCH ANALYST 2 6000
RESEARCH MANAGER 1 2975 > Level 2
RESEARCH 5 10875
ACCOUNTING CLERK 1 1300
ACCOUNTING MANAGER 1 2450
ACCOUNTING PRESIDENT 1 5000
ACCOUNTING 3 8750 > Level 2
14 29025 > Level 3
13 rows selected.
* L1 - GROUP BY 수행시 생성되는 표준 집계 (9건)
* L2 - DNAME 별 모든 JOB의 SUBTOTAL (3건)
* L3 - GRAND TOTAL (마지막 행, 1건)
추가로 ROLLUP의 경우 계층 간 집계에 대해서는 LEVEL 별 순서(L1→L2→L3)를 정렬하지만,
계층 내 GROUP BY 수행시 생성되는 표준 집계에는 별도의 정렬을 지원하지 않는다.
L1, L2, L3 계층 내 정렬을 위해서는 별도의 ORDER BY 절을 사용해야 한다
Useful Information
STEP 3. GROUPING 함수 사용
SELECT DNAME
, GROUPING(DNAME)
, JOB
, GROUPING(JOB)
, COUNT(*) "Total Empl"
, SUM(SAL) "Total Sal"
FROM EMP, DEPT
WHERE DEPT.DEPTNO = EMP.DEPTNO
GROUP BY ROLLUP (DNAME, 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 rows selected.
STEP 4. GROUPING 함수 + CASE 사용
SELECT CASE GROUPING(DNAME) WHEN 1 THEN 'All Departments' ELSE DNAME END AS DNAME
, CASE GROUPING(JOB) WHEN 1 THEN 'All Jobs' ELSE JOB END AS JOB
, COUNT(*) "Total Empl", SUM(SAL) "Total Sal"
FROM EMP, DEPT
WHERE DEPT.DEPTNO = EMP.DEPTNO
GROUP BY ROLLUP (DNAME, 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 rows selected.
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 ROLLUP (DNAME, 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 rows selected.
STEP 4-2. ROLLUP 함수 일부 사용
SELECT CASE GROUPING(DNAME) WHEN 1 THEN 'All Departments' ELSE DNAME END AS DNAME,
CASE GROUPING(JOB) WHEN 1 THEN 'All Jobs' ELSE JOB END AS JOB,
COUNT(*) "Total Empl", SUM(SAL) "Total Sal"
FROM EMP, DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO
GROUP BY DNAME, ROLLUP(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
12 rows selected.
결과는 마지막 ALL DEPARTMENTS & ALL JOBS 줄만 계산이 되지 않았다.
ROLLUP이 JOB 칼럼에만 사용되었기 때문에 DNAME에 대한 집계는 필요하지 않기 때문이다.
STEP 4-3. ROLLUP 함수 결합 칼럼 사용
SELECT DNAME, JOB, MGR, SUM(SAL) "Total Sal"
FROM EMP, DEPT
WHERE DEPT.DEPTNO = EMP.DEPTNO
GROUP BY ROLLUP (DNAME, (JOB, 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 rows selected.
Useful Information
GROUP BY ROLLUP (DNAME, JOB) 조건에서 GROUP BY CUBE (DNAME, JOB) 조건으로 변경해서 수행한다
SELECT CASE GROUPING(DNAME) WHEN 1 THEN 'All Departments' ELSE DNAME END AS DNAME,
CASE GROUPING(JOB) WHEN 1 THEN 'All Jobs' ELSE JOB END AS JOB,
COUNT(*) "Total Empl", SUM(SAL) "Total Sal"
FROM EMP, DEPT WHERE DEPT.DEPTNO = EMP.DEPTNO
GROUP BY CUBE (DNAME, 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 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 4232949899
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 756 | 8 (25)| 00:00:01 |
| 1 | SORT GROUP BY | | 14 | 756 | 8 (25)| 00:00:01 |
| 2 | GENERATE CUBE | | 14 | 756 | 8 (25)| 00:00:01 |
| 3 | SORT GROUP BY | | 14 | 756 | 8 (25)| 00:00:01 |
|* 4 | HASH JOIN | | 14 | 756 | 7 (15)| 00:00:01 |
| 5 | TABLE ACCESS STORAGE FULL| DEPT | 4 | 88 | 3 (0)| 00:00:01 |
| 6 | TABLE ACCESS STORAGE FULL| EMP | 14 | 448 | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("DEPT"."DEPTNO"="EMP"."DEPTNO")
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
7 recursive calls
0 db block gets
30 consistent gets
0 physical reads
0 redo size
1353 bytes sent via SQL*Net to client
534 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
2 sorts (memory)
0 sorts (disk)
18 rows processed
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;
DNAME JOB Total Empl Total Sal
--------------- --------- ---------- ----------
SALES MANAGER 1 2850
SALES CLERK 1 950
ACCOUNTING MANAGER 1 2450
ACCOUNTING PRESIDENT 1 5000
ACCOUNTING CLERK 1 1300
SALES SALESMAN 4 5600
RESEARCH MANAGER 1 2975
RESEARCH ANALYST 2 6000
RESEARCH CLERK 2 1900
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
All Departments All Jobs 14 29025
18 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 2199532226
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 43 | 2097 | 29 (80)| 00:00:01 |
| 1 | UNION-ALL | | | | | |
| 2 | HASH GROUP BY | | 14 | 756 | 8 (25)| 00:00:01 |
|* 3 | HASH JOIN | | 14 | 756 | 7 (15)| 00:00:01 |
| 4 | TABLE ACCESS STORAGE FULL| DEPT | 4 | 88 | 3 (0)| 00:00:01 |
| 5 | TABLE ACCESS STORAGE FULL| EMP | 14 | 448 | 3 (0)| 00:00:01 |
| 6 | HASH GROUP BY | | 14 | 672 | 8 (25)| 00:00:01 |
|* 7 | HASH JOIN | | 14 | 672 | 7 (15)| 00:00:01 |
| 8 | TABLE ACCESS STORAGE FULL| DEPT | 4 | 88 | 3 (0)| 00:00:01 |
| 9 | TABLE ACCESS STORAGE FULL| EMP | 14 | 364 | 3 (0)| 00:00:01 |
| 10 | HASH GROUP BY | | 14 | 630 | 8 (25)| 00:00:01 |
|* 11 | HASH JOIN | | 14 | 630 | 7 (15)| 00:00:01 |
| 12 | TABLE ACCESS STORAGE FULL| DEPT | 4 | 52 | 3 (0)| 00:00:01 |
| 13 | TABLE ACCESS STORAGE FULL| EMP | 14 | 448 | 3 (0)| 00:00:01 |
| 14 | SORT AGGREGATE | | 1 | 39 | | |
|* 15 | HASH JOIN | | 14 | 546 | 7 (15)| 00:00:01 |
| 16 | TABLE ACCESS STORAGE FULL| DEPT | 4 | 52 | 3 (0)| 00:00:01 |
| 17 | TABLE ACCESS STORAGE FULL| EMP | 14 | 364 | 3 (0)| 00:00:01 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("DEPT"."DEPTNO"="EMP"."DEPTNO")
7 - access("DEPT"."DEPTNO"="EMP"."DEPTNO")
11 - access("DEPT"."DEPTNO"="EMP"."DEPTNO")
15 - access("DEPT"."DEPTNO"="EMP"."DEPTNO")
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
56 consistent gets
0 physical reads
0 redo size
1354 bytes sent via SQL*Net to client
534 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
18 rows processed
Useful Information
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 (JOB, DNAME);
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 rows selected.
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
SALES MANAGER 7839 2850
SALES SALESMAN 7698 5600
RESEARCH CLERK 7788 1100
RESEARCH CLERK 7902 800
RESEARCH ANALYST 7566 6000
RESEARCH MANAGER 7839 2975
ACCOUNTING CLERK 7782 1300
ACCOUNTING MANAGER 7839 2450
ACCOUNTING PRESIDENT 5000
SALES CLERK 950
SALES MANAGER 2850
SALES SALESMAN 5600
RESEARCH CLERK 1900
RESEARCH ANALYST 6000
RESEARCH MANAGER 2975
ACCOUNTING CLERK 1300
ACCOUNTING MANAGER 2450
ACCOUNTING PRESIDENT 5000
CLERK 7698 950
CLERK 7902 800
PRESIDENT 5000
CLERK 7788 1100
CLERK 7782 1300
SALESMAN 7698 5600
MANAGER 7839 8275
ANALYST 7566 6000
27 rows selected.
- 강좌 URL : http://www.gurubee.net/lecture/2381
- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.