•
ROLLUP 으로 계층적 소계 + 총계를 한 번에 구할 수 있다.
•
CUBE 로 모든 조합의 소계를 구하고, ROLLUP 과의 차이를 안다.
•
생성되는 소계 개수(ROLLUP N+1, CUBE 2ᴺ)를 계산할 수 있다.
•
GROUPING 함수로 소계 행과 실제 NULL을 구분할 수 있다.
1. 왜 필요한가
1) 소계·총계를 따로 구하던 불편함
"부서별 급여합계 + 전체 급여합계"를 함께 보려면 예전엔 UNION 을 써야 했습니다.
-- ============================================================
-- 옛날 방식 : GROUP BY + UNION ALL (번거롭다)
-- ============================================================
SELECT TO_CHAR(DEPTNO) AS 부서, SUM(SAL) FROM EMP GROUP BY DEPTNO
UNION ALL
SELECT '전체합계', SUM(SAL) FROM EMP; -- 총계를 따로 붙임
-- 부서 SUM(SAL)
-- --------- --------
-- 10 8750
-- 20 10875
-- 30 9400
-- 전체합계 29025
--
-- ⚠️ 소계 종류가 늘면 UNION 을 계속 추가해야 한다. → ROLLUP 이면 한 줄로 끝난다.
SQL
복사
ROLLUP · CUBE 는 소계와 총계를 자동으로 생성해 주는 GROUP BY 의 확장입니다.2. ROLLUP — 계층적 소계 + 총계 


1) ROLLUP(A, B) 이 만드는 것
-- ============================================================
-- 【이해용 예제】 부서별·직무별 급여합계 + 부서 소계 + 총계 ★★
-- ============================================================
SELECT DEPTNO, JOB, SUM(SAL) AS 급여합계
FROM EMP
GROUP BY ROLLUP(DEPTNO, JOB)
ORDER BY DEPTNO, JOB;
-- DEPTNO JOB 급여합계
-- ------ --------- --------
-- 10 CLERK 1300
-- 10 MANAGER 2450
-- 10 PRESIDENT 5000
-- 10 (NULL) 8750 ← ★ 10번 부서 소계 (JOB이 NULL)
-- 20 ANALYST 6000
-- 20 CLERK 1900
-- 20 MANAGER 2975
-- 20 (NULL) 10875 ← ★ 20번 부서 소계
-- 30 CLERK 950
-- 30 MANAGER 2850
-- 30 SALESMAN 5600
-- 30 (NULL) 9400 ← ★ 30번 부서 소계
-- (NULL)(NULL) 29025 ← ★★ 전체 총계 (DEPTNO, JOB 모두 NULL)
--
-- ⭐ 소계 행에서는 뭉개진 컬럼이 'NULL' 로 표시된다.
-- JOB이 NULL = "이 부서의 모든 직무 합계"라는 뜻.
SQL
복사
2)
인자 순서가 결과를 바꾼다 

-- ROLLUP(DEPTNO, JOB) → 부서별 소계 생성 (JOB 을 먼저 뭉갬)
-- ROLLUP(JOB, DEPTNO) → 직무별 소계 생성 (DEPTNO 를 먼저 뭉갬)
SELECT JOB, DEPTNO, SUM(SAL)
FROM EMP
GROUP BY ROLLUP(JOB, DEPTNO);
-- → CLERK 소계, MANAGER 소계, ... 처럼 '직무별' 소계가 생긴다
--
-- ⭐ ROLLUP 은 '계층적' 이라 순서가 중요하다.
-- ROLLUP(A, B) : (A,B) → A소계 → 총계 (오른쪽부터 뭉갬)
-- ROLLUP(B, A) : (B,A) → B소계 → 총계
-- → ROLLUP(A,B) ≠ ROLLUP(B,A)
SQL
복사
3) 소계 개수 = N + 1 
ROLLUP 인자 | 소계 레벨 |
ROLLUP(A) | 2개 (A별 + 총계) |
ROLLUP(A, B) | 3개 (AB조합 + A소계 + 총계) |
ROLLUP(A, B, C) | 4개 |
ROLLUP(인자 N개) | N + 1개 |
3. CUBE — 모든 조합의 소계 


1) CUBE(A, B) 이 만드는 것
-- ============================================================
-- 【시험용 예제】 CUBE 는 '직무별 소계' 까지 추가로 만든다 ★★★
-- ============================================================
SELECT DEPTNO, JOB, SUM(SAL) AS 급여합계
FROM EMP
GROUP BY CUBE(DEPTNO, JOB)
ORDER BY DEPTNO, JOB;
-- DEPTNO JOB 급여합계
-- ------ --------- --------
-- 10 CLERK 1300
-- 10 MANAGER 2450
-- ... (부서·직무 조합들)
-- 10 (NULL) 8750 ← 부서별 소계 (ROLLUP에도 있음)
-- 20 (NULL) 10875
-- 30 (NULL) 9400
-- (NULL)ANALYST 6000 ← ★ 직무별 소계 (CUBE에만!)
-- (NULL)CLERK 4150 ← ★ 전 부서 CLERK 합계
-- (NULL)MANAGER 8275 ← ★
-- (NULL)PRESIDENT 5000 ← ★
-- (NULL)SALESMAN 5600 ← ★
-- (NULL)(NULL) 29025 ← 전체 총계
--
-- ⭐ CUBE = ROLLUP 이 만드는 것 + 'JOB별 소계' 까지 전부.
-- DEPTNO(NULL) & JOB(값) 인 행 = "그 직무의 전 부서 합계"
SQL
복사
2) CUBE는 순서 무관 
-- CUBE 는 모든 조합을 만들므로 인자 순서가 결과에 영향 없다
-- CUBE(A, B) = CUBE(B, A) ← 정렬 순서만 다를 뿐 내용은 같음
SQL
복사
3) 소계 개수 = 2ᴺ 
CUBE 인자 | 소계 레벨 |
CUBE(A) | 2개 (A별 + 총계) |
CUBE(A, B) | 4개 (AB + A + B + 총계) |
CUBE(A, B, C) | 8개 |
CUBE(인자 N개) | 2ᴺ개 |
4. ROLLUP vs CUBE 비교 

ROLLUP(A, B) | CUBE(A, B) | |
생성 소계 | (A,B), A별, 총계 | (A,B), A별, B별, 총계 |
소계 레벨 수 | N+1 (3개) | 2ᴺ (4개) |
인자 순서 | 중요 (A≠B) | 무관 |
용도 | 계층적 소계 (연도>월>일) | 모든 각도 소계 |
핵심 차이: CUBE 는 ROLLUP 이 안 만드는 "B별 소계" 를 추가로 만듭니다.
그래서 CUBE 의 결과 행이 더 많습니다.5. GROUPING SETS — 원하는 그룹만 
-- ============================================================
-- 【시험용 예제】 부서별 소계와 직무별 소계'만' 콕 집어서 ★
-- (조합별 상세도, 총계도 필요 없고 딱 두 소계만)
-- ============================================================
SELECT DEPTNO, JOB, SUM(SAL) AS 급여합계
FROM EMP
GROUP BY GROUPING SETS(DEPTNO, JOB); -- 부서별, 직무별 두 가지만
-- DEPTNO JOB 급여합계
-- ------ --------- --------
-- 10 (NULL) 8750 ┐
-- 20 (NULL) 10875 │ 부서별 소계
-- 30 (NULL) 9400 ┘
-- (NULL)ANALYST 6000 ┐
-- (NULL)CLERK 4150 │
-- (NULL)MANAGER 8275 │ 직무별 소계
-- (NULL)PRESIDENT 5000 │
-- (NULL)SALESMAN 5600 ┘
--
-- ⭐ GROUPING SETS(A, B) = A별 소계 + B별 소계 (조합·총계 없음)
-- 필요한 소계만 콕 집어 지정할 수 있다.
SQL
복사
표현 | 만드는 것 |
GROUPING SETS(A, B) | A별 + B별 |
GROUPING SETS((A,B), A) | AB조합 + A별 |
GROUPING SETS(A, ()) | A별 + 총계 (빈 괄호 = 총계) |
6. GROUPING 함수 — 소계 행 판별 

1) 소계 NULL과 실제 NULL 구분
문제: 소계 행은 뭉개진 컬럼이 NULL로 표시됩니다. 그런데 이게 실제 데이터의 NULL과 구분이 안 됩니다.
-- ============================================================
-- 【시험용 예제】 GROUPING 으로 소계 행을 식별 ★★
-- ============================================================
SELECT DEPTNO, JOB, SUM(SAL),
GROUPING(DEPTNO) AS G_부서, -- 소계로 뭉개진 컬럼이면 1, 실제 값이면 0
GROUPING(JOB) AS G_직무
FROM EMP
GROUP BY ROLLUP(DEPTNO, JOB);
-- DEPTNO JOB SUM(SAL) G_부서 G_직무
-- ------ --------- -------- ------ ------
-- 10 CLERK 1300 0 0 ← 일반 행 (둘 다 실제 값)
-- 10 (NULL) 8750 0 1 ← 부서 소계 (JOB이 뭉개짐)
-- (NULL)(NULL) 29025 1 1 ← 총계 (둘 다 뭉개짐)
--
-- ⭐ GROUPING(컬럼) = 1 → 그 컬럼이 소계 때문에 NULL이 된 것
-- GROUPING(컬럼) = 0 → 실제 값 (또는 실제 NULL)
SQL
복사
2) GROUPING + CASE 로 소계 라벨 붙이기 
-- ============================================================
-- 【시험용 예제】 소계 행에 '합계' 라벨 달기 (실전 보고서) ★★
-- ============================================================
SELECT CASE WHEN GROUPING(DEPTNO) = 1 THEN '전체합계' -- 총계 행
ELSE TO_CHAR(DEPTNO) END AS 부서,
CASE WHEN GROUPING(JOB) = 1 AND GROUPING(DEPTNO) = 0 THEN '부서소계'
WHEN GROUPING(JOB) = 1 THEN ' '
ELSE JOB END AS 직무,
SUM(SAL) AS 급여합계
FROM EMP
GROUP BY ROLLUP(DEPTNO, JOB);
-- 부서 직무 급여합계
-- --------- ---------- --------
-- 10 CLERK 1300
-- 10 부서소계 8750
-- ...
-- 전체합계 29025
--
-- ⚠️ 만약 NVL 로 그냥 '합계' 라 쓰면, '실제 데이터의 NULL' 도 '합계' 가 되어버린다.
-- 그래서 소계 판별은 반드시 GROUPING 함수를 써야 한다. (06강 NULL 구분)
SQL
복사
7. 출제 포인트 한눈에 정리
# | 꼭 외울 것 | 핵심 |
1 | 그룹 함수 목적 | 소계·총계를 자동 생성 |
2 | ROLLUP(A,B) | (A,B) + A별 소계 + 총계 |
3 | ROLLUP 소계 개수 | N + 1 ![]() |
4 | ROLLUP 인자 순서 | 중요 (A,B ≠ B,A) ![]() |
5 | CUBE(A,B) | (A,B) + A별 + B별 + 총계 |
6 | CUBE 소계 개수 | 2ᴺ ![]() |
7 | CUBE 인자 순서 | 무관 |
8 | ROLLUP vs CUBE | CUBE가 B별 소계를 추가 |
9 | GROUPING SETS | 지정한 그룹만 |
10 | 빈 괄호 () | 총계를 의미 |
11 | 소계 행의 그룹컬럼 | NULL로 표시 |
12 | GROUPING(컬럼) | 소계로 뭉개진 컬럼이면 1, 아니면 0 ![]() |
13 | 소계 라벨 | GROUPING + CASE (NVL 아님) |
14 | 실제 NULL 구분 | GROUPING 으로만 정확히 구분 |
8. 확인 문제
Q1. GROUP BY ROLLUP(DEPTNO, JOB) 은 어떤 집계를 만드는가?
정답 보기
Q2. ROLLUP(A, B, C) 가 만드는 소계 레벨의 개수는?
정답 보기
Q3. ROLLUP(DEPTNO, JOB) 과 ROLLUP(JOB, DEPTNO) 의 결과가 다른 이유는?
정답 보기
Q4. CUBE(A, B) 가 ROLLUP(A, B) 보다 추가로 만드는 소계는?
정답 보기
Q5. CUBE(A, B, C) 가 만드는 소계 레벨 개수는?
정답 보기
Q6. 부서별 소계와 직무별 소계'만' 원할 때 (조합·총계 제외) 사용하는 것은?
정답 보기






