2025-08-20 22:32
데이터 분석 핸드북 ROLLUP과 CUBE, 총정리 개념부터 실전 활용까지
데이터의 바다에서 의미 있는 정보를 건져 올리는 일은 마치 보물찾기와 같습니다. 수많은 데이터 속에서 우리는 패턴을 찾고, 요약하며, 비즈니스에 도움이 될 인사이트를 발견해야 합니다. 이때 SQL의 GROUP BY
절은 데이터를 그룹화하여 집계하는 데 필수적인 도구입니다. 하지만 단순히 그룹별 집계만으로는 충분하지 않을 때가 많습니다. 그룹별 소계(Subtotal)와 전체 총계(Grand Total)를 한 번에 보고 싶다면 어떻게 해야 할까요?
과거에는 여러 개의 GROUP BY
쿼리를 작성하고 UNION ALL
로 합치는 복잡하고 비효율적인 방식을 사용해야 했습니다. 이는 쿼리를 작성하는 시간도 오래 걸릴뿐더러, 데이터베이스 시스템에도 여러 번 테이블에 접근해야 하는 부담을 주었습니다.
이러한 문제를 해결하기 위해 등장한 것이 바로 ROLLUP
과 CUBE
입니다. 이들은 GROUP BY
의 확장 기능으로, 단 하나의 쿼리만으로 다양한 수준의 집계 데이터를 매우 효율적으로 생성해 주는 강력한 무기입니다.
이 핸드북에서는 ROLLUP
과 CUBE
가 왜 만들어졌는지, 어떤 구조로 동작하는지, 그리고 실제 업무에서 어떻게 활용할 수 있는지에 대해 A부터 Z까지 상세하게 알아보겠습니다. 마치 잘 짜인 레고 블록처럼, 데이터를 원하는 대로 쌓아 올리고 분석하는 즐거움을 느끼게 될 것입니다.
1. ROLLUP
과 CUBE
의 탄생 배경: 왜 필요했을까?
ROLLUP
과 CUBE
의 등장은 OLAP(Online Analytical Processing, 온라인 분석 처리) 이라는 개념과 깊은 관련이 있습니다. OLAP은 사용자가 다차원적인 데이터를 다양한 관점에서 빠르고 쉽게 분석할 수 있도록 지원하는 기술입니다. 예를 들어, ‘지역별’, ‘제품별’, ‘시간별’ 매출 데이터를 분석한다고 상상해 봅시다.
사용자는 다음과 같은 다양한 질문을 던질 수 있습니다.
-
각 지역의 총매출은 얼마인가?
-
각 제품 카테고리별 총매출은 얼마인가?
-
특정 지역의 특정 제품 카테고리 매출은 얼마인가?
-
전체 총매출은 얼마인가?
이러한 질문에 답하기 위해 매번 다른 GROUP BY
쿼리를 작성하는 것은 매우 번거롭습니다. ROLLUP
과 CUBE
는 바로 이런 다차원 분석의 요구를 충족시키기 위해 탄생했습니다. 이들은 하나의 쿼리로 위 질문들에 대한 답, 즉 다양한 수준의 집계 결과를 모두 제공하여 데이터 분석 과정을 획기적으로 단축하고 효율성을 높여줍니다.
비유하자면, ROLLUP
과 CUBE
는 잘 정리된 보고서를 자동으로 생성해 주는 비서와 같습니다. 단순히 원본 데이터(Raw Data)만 주는 것이 아니라, 각 항목별 소계와 전체 총계까지 보기 좋게 정리해서 한 번에 보여주는 것이죠.
2. 계층적 집계의 전문가: ROLLUP
파헤치기
ROLLUP
은 이름에서 알 수 있듯이, 데이터를 ‘말아 올리면서’ 계층적인 소계를 생성하는 데 특화된 기능입니다. GROUP BY ROLLUP(A, B, C)
와 같이 사용하면, 오른쪽에서 왼쪽으로 컬럼을 하나씩 제거해가며 각 단계별 소계를 계산하고 마지막에는 전체 총계를 보여줍니다.
ROLLUP의 동작 원리
ROLLUP(A, B, C)
는 내부적으로 다음과 같은 GROUP BY
조합을 UNION ALL
로 합친 것과 동일하게 동작합니다.
-
GROUP BY A, B, C
(가장 상세한 레벨) -
GROUP BY A, B
(C를 말아 올림) -
GROUP BY A
(B, C를 말아 올림) -
GROUP BY ()
(전체 총계)
핵심은 ‘순서’입니다. ROLLUP
은 인자로 주어진 컬럼의 순서를 엄격하게 따릅니다. ROLLUP(A, B)
와 ROLLUP(B, A)
는 완전히 다른 결과를 생성합니다. 이는 마치 ‘국가 > 도시’와 같은 명확한 계층 구조를 가진 데이터를 분석할 때 매우 유용합니다.
ROLLUP 기본 구조 및 사용법
SELECT column1, column2, AGGREGATE_FUNCTION(column3)
FROM table_name
GROUP BY ROLLUP(column1, column2);
예시: 지역별, 부서별 매출 집계
sales
테이블에 region
(지역), department
(부서), amount
(매출액) 컬럼이 있다고 가정해 봅시다.
SELECT
region,
department,
SUM(amount) AS total_sales
FROM
sales
GROUP BY
ROLLUP(region, department);
이 쿼리의 결과는 다음과 같은 형태로 나타납니다.
region | department | total_sales | 설명 |
---|---|---|---|
서울 | 영업1팀 | 1500 | (서울, 영업1팀) 집계 |
서울 | 영업2팀 | 2000 | (서울, 영업2팀) 집계 |
서울 | NULL | 3500 | 서울 지역 소계 |
부산 | 영업1팀 | 1200 | (부산, 영업1팀) 집계 |
부산 | 영업2팀 | 1800 | (부산, 영업2팀) 집계 |
부산 | NULL | 3000 | 부산 지역 소계 |
NULL | NULL | 6500 | 전체 총계 |
결과 테이블에서 department
컬럼이 NULL
인 행은 각 region
의 소계를 의미하며, region
과 department
가 모두 NULL
인 행은 전체 총계를 나타냅니다. 이처럼 ROLLUP
은 지정된 계층을 따라 자연스럽게 상위 레벨의 집계를 생성합니다.
3. 다차원 분석의 마법사: CUBE
파헤치기
CUBE
는 ROLLUP
보다 한 단계 더 나아가, 인자로 주어진 컬럼들의 모든 가능한 조합에 대한 소계를 생성합니다. ROLLUP
이 계층이라는 한 방향으로만 집계를 생성했다면, CUBE
는 마치 큐브(정육면체)의 모든 면을 돌려보듯 다차원적인 관점에서 데이터를 분석합니다.
CUBE의 동작 원리
CUBE(A, B, C)
는 내부적으로 다음과 같은 모든 조합의 GROUP BY
를 UNION ALL
로 합친 것과 동일하게 동작합니다.
-
GROUP BY A, B, C
-
GROUP BY A, B
-
GROUP BY A, C
-
GROUP BY B, C
-
GROUP BY A
-
GROUP BY B
-
GROUP BY C
-
GROUP BY ()
(전체 총계)
ROLLUP
과 달리 ‘순서’가 중요하지 않습니다. CUBE(A, B)
와 CUBE(B, A)
는 결과의 순서는 다를 수 있지만, 생성되는 집계 조합의 종류는 동일합니다. 인자로 N개의 컬럼이 주어지면, CUBE는 2^N 개의 그룹핑 레벨을 생성합니다.
CUBE 기본 구조 및 사용법
SELECT column1, column2, AGGREGATE_FUNCTION(column3)
FROM table_name
GROUP BY CUBE(column1, column2);
예시: 지역별, 부서별 매출 집계 (CUBE Ver.)
앞서 사용한 sales
테이블에 CUBE
를 적용해 보겠습니다.
SELECT
region,
department,
SUM(amount) AS total_sales
FROM
sales
GROUP BY
CUBE(region, department);
이 쿼리의 결과는 ROLLUP
의 결과에 추가적인 집계가 포함됩니다.
region | department | total_sales | 설명 |
---|---|---|---|
서울 | 영업1팀 | 1500 | (서울, 영업1팀) 집계 |
서울 | 영업2팀 | 2000 | (서울, 영업2팀) 집계 |
서울 | NULL | 3500 | 서울 지역 소계 |
부산 | 영업1팀 | 1200 | (부산, 영업1팀) 집계 |
부산 | 영업2팀 | 1800 | (부산, 영업2팀) 집계 |
부산 | NULL | 3000 | 부산 지역 소계 |
NULL | 영업1팀 | 2700 | 영업1팀 전체 소계 (CUBE에만 존재) |
NULL | 영업2팀 | 3800 | 영업2팀 전체 소계 (CUBE에만 존재) |
NULL | NULL | 6500 | 전체 총계 |
ROLLUP
결과에서는 볼 수 없었던, region
과 무관한 각 department
별 전체 소계가 추가된 것을 확인할 수 있습니다. 이처럼 CUBE
는 특정 계층에 얽매이지 않고 모든 가능한 조합의 인사이트를 제공합니다.
4. ROLLUP
vs CUBE
: 한눈에 보는 비교 분석
구분 | ROLLUP | CUBE |
---|---|---|
핵심 개념 | 계층적(Hierarchical) 집계 | 조합적(Combinational) 집계 |
집계 방식 | 지정된 컬럼 순서를 따라 상위 레벨 소계 생성 | 지정된 컬럼들의 모든 가능한 조합에 대한 소계 생성 |
컬럼 순서 | 매우 중요함. 순서에 따라 결과가 달라짐. | 중요하지 않음. 조합의 종류는 동일함. |
생성되는 그룹 수 | N개의 컬럼에 대해 N+1개 | N개의 컬럼에 대해 2^N개 |
주요 사용 사례 | 국가 > 도시 > 지역과 같은 명확한 계층 구조 데이터 분석 | 교차 분석(Cross-tabulation) 보고서, 다차원 분석 |
비유 | 조직도: 사원 → 팀장 → 부서장 → CEO | 회의 참석자 명단: 가능한 모든 소그룹 조합 |
5. 실전 활용 시나리오: 언제 무엇을 써야 할까?
ROLLUP
이 빛을 발하는 순간 ✨
ROLLUP
은 데이터에 명확한 상하 관계, 즉 계층 구조가 존재할 때 가장 이상적입니다.
-
시간 기반 리포트: 년(Year) > 분기(Quarter) > 월(Month) > 일(Day) 순서로 매출을 집계할 때
-
지역 기반 리포트: 대륙 > 국가 > 도시 순서로 사용자 수를 집계할 때
-
제품 카테고리 리포트: 대분류 > 중분류 > 소분류 순서로 재고를 집계할 때
이러한 경우, ROLLUP(년, 분기, 월)
과 같이 계층의 상위 레벨부터 순서대로 인자를 지정하면 매우 직관적이고 유용한 보고서를 손쉽게 만들 수 있습니다.
CUBE
가 필요한 순간 🚀
CUBE
는 여러 차원(Dimension)을 교차하여 다각도로 분석하고 싶을 때 강력한 힘을 발휘합니다. 특정 계층에 얽매이지 않고 모든 가능성을 탐색해야 할 때 적합합니다.
-
시장 분석: ‘제품’, ‘고객 연령대’, ‘지역’이라는 세 가지 차원을 조합하여 각 조합별 판매량을 분석할 때
-
성과 분석: ‘직원’, ‘프로젝트’, ‘작업 유형’을 조합하여 각 조합별 소요 시간을 분석할 때
-
재무 분석: ‘계정 과목’, ‘부서’, ‘분기’를 조합하여 비용을 다각도로 분석할 때
CUBE(제품, 연령대, 지역)
과 같은 쿼리는 “A 제품을 구매한 20대 서울 거주자”부터 “전체 지역의 30대 고객”, “B 제품의 전체 연령대 판매량”까지 모든 조합의 집계를 한 번에 제공하여 숨겨진 인사이트를 발견할 기회를 높여줍니다.
6. 심화 학습: GROUPING
함수로 NULL의 모호성 해결하기
ROLLUP
이나 CUBE
를 사용하면 소계나 총계를 나타내는 행에 NULL
이 표시됩니다. 그런데 만약 원래 데이터 자체에 NULL
값이 포함되어 있다면 어떻게 될까요? 이 둘을 구분할 방법이 필요합니다. 이때 사용하는 것이 바로 GROUPING()
함수입니다.
GROUPING(컬럼명)
함수는 해당 컬럼이 ROLLUP
이나 CUBE
에 의해 집계되어 NULL
이 된 것이면 1을 반환하고, 원래 데이터의 NULL
이거나 일반 데이터 행이면 0을 반환합니다.
이를 CASE
문과 함께 사용하면 보고서의 가독성을 크게 향상시킬 수 있습니다.
GROUPING
함수 활용 예시
SELECT
CASE
WHEN GROUPING(region) = 1 THEN '전체 지역'
ELSE region
END AS region_name,
CASE
WHEN GROUPING(department) = 1 THEN '부서 합계'
ELSE department
END AS department_name,
SUM(amount) AS total_sales
FROM
sales
GROUP BY
ROLLUP(region, department);
결과:
region_name | department_name | total_sales |
---|---|---|
서울 | 영업1팀 | 1500 |
서울 | 영업2팀 | 2000 |
서울 | 부서 합계 | 3500 |
부산 | 영업1팀 | 1200 |
부산 | 영업2팀 | 1800 |
부산 | 부서 합계 | 3000 |
전체 지역 | 부서 합계 | 6500 |
이제 NULL
대신 ‘전체 지역’, ‘부서 합계’와 같이 명확한 텍스트가 표시되어 훨씬 이해하기 쉬운 보고서가 완성되었습니다.
핸드북의 6장 내용처럼 ROLLUP
이나 CUBE
를 사용하면 소계나 총계를 나타내는 행에 NULL
값이 표시되는데요, 이때 원래 데이터에 있던 NULL
과 구별하기 어려워지는 문제가 생깁니다.
GROUPING
함수는 바로 이 문제를 해결하기 위해 사용됩니다.
쉽게 말해, “이 NULL
값이 집계(소계/총계) 때문에 생긴 건가요, 아니면 원래 데이터에 있던 건가요?” 라는 질문에 답을 해주는 함수입니다.
동작 방식
-
GROUPING(컬럼명)
의 결과가 1이면: 해당NULL
은ROLLUP
이나CUBE
에 의해 만들어진 소계 또는 총계 행이라는 의미입니다. -
GROUPING(컬럼명)
의 결과가 0이면: 일반 데이터 행이라는 의미입니다. (원래 데이터가NULL
인 경우도 포함)
사용 예시
핸드북의 예시처럼 CASE
문과 함께 사용하면 NULL
대신 훨씬 이해하기 쉬운 텍스트를 넣을 수 있습니다.
SQL
SELECT
CASE
WHEN GROUPING(region) = 1 THEN '전체 지역 합계' -- region이 집계되어 NULL이 되면 1을 반환
ELSE region
END AS region_name,
SUM(amount) AS total_sales
FROM
sales
GROUP BY
ROLLUP(region);
이렇게 하면 결과 테이블의 NULL
값이 ‘전체 지역 합계’와 같이 명확하게 표시되어 보고서의 가독성이 크게 향상됩니다.
네, DECODE
함수에 대해 설명해 드릴게요.
DECODE
함수는 SQL에서 IF-THEN-ELSE와 같은 조건부 로직을 구현하는 함수입니다. 특정 값이나 컬럼의 값을 확인해서, 조건에 따라 다른 값을 반환하고 싶을 때 사용합니다. 주로 Oracle 데이터베이스에서 많이 사용됩니다.
기본 구조
DECODE
는 짝수 개의 인자(파라미터)를 가질 수 있으며, 기본 구조는 다음과 같습니다.
SQL
DECODE (검사할_값, 조건1, 결과1, 조건2, 결과2, ..., 기본_결과)
-
검사할_값: 비교의 기준이 되는 컬럼이나 값입니다.
-
조건1, 결과1:
검사할_값
이조건1
과 같으면결과1
을 반환합니다. -
조건2, 결과2:
검사할_값
이조건2
와 같으면결과2
를 반환합니다. -
기본_결과: 위에 있는 어떤 조건과도 일치하지 않을 때 반환되는 값입니다. 이 부분은 생략 가능하며, 생략 시 일치하는 조건이 없으면
NULL
을 반환합니다.
간단한 사용 예시
직원 테이블(employees
)에 성별을 나타내는 gender
컬럼이 ‘M’, ‘F’로 저장되어 있다고 가정해 봅시다. 이를 ‘남성’, ‘여성’으로 바꿔서 보고 싶을 때 DECODE
를 사용할 수 있습니다.
SQL
SELECT
emp_name,
DECODE(gender, 'M', '남성', 'F', '여성') AS gender_text
FROM
employees;
동작 방식:
-
gender
컬럼의 값을 가져옵니다. -
값이 ‘M’과 같으면 ‘남성’을 반환합니다.
-
값이 ‘F’와 같으면 ‘여성’을 반환합니다.
DECODE
와 CASE
문의 차이점
DECODE
와 비슷한 역할을 하는 것으로 표준 SQL의 CASE
문이 있습니다. 둘의 주요 차이점은 다음과 같습니다.
구분 | DECODE 함수 | CASE 표현식 |
---|---|---|
표준 | Oracle 전용 함수 | ANSI 표준 SQL (대부분의 DB에서 사용 가능) |
기능 | **동등 비교(= )**만 가능 | 동등 비교뿐만 아니라 부등호(> , < ) 등 다양한 비교 가능 |
가독성 | 조건이 간단할 때는 간결함 | 조건이 복잡해져도 논리 구조를 파악하기 쉬움 |
결론적으로, DECODE
는 간단한 값 비교에 편리하지만, 다른 데이터베이스와의 호환성이나 복잡한 조건을 처리해야 할 때는 표준 SQL인 CASE
문을 사용하는 것이 더 좋습니다.
네, GROUPING SETS
함수에 대해 설명해 드릴게요. ROLLUP
과 CUBE
가 정해진 규칙(계층, 모든 조합)에 따라 소계를 만드는 반면, GROUPING SETS
는 사용자가 원하는 그룹 조합을 직접 지정해서 소계를 만들 수 있는 가장 유연하고 강력한 기능입니다.
비유하자면,
-
ROLLUP
: 정해진 코스 요리 (A → A,B → A,B,C) -
CUBE
: 모든 메뉴를 다 맛보는 뷔페 (A, B, C, AB, AC, BC, ABC…) -
GROUPING SETS
: 원하는 메뉴만 골라 주문하는 ‘단품(à la carte)’ 요리
GROUPING SETS의 핵심: 원하는 대로 조합하기
GROUPING SETS
의 가장 큰 장점은 필요한 집계만 정확히 골라서 볼 수 있다는 점입니다. ROLLUP
이나 CUBE
가 불필요한 소계까지 모두 보여주는 것과 달리, GROUPING SETS
는 원하는 조합만 명시하면 됩니다.
기본 구조 및 사용법
괄호 ()
안에 원하는 그룹 조합을 쉼표(,
)로 구분하여 나열합니다.
SQL
SELECT region, department, SUM(amount)
FROM sales
GROUP BY GROUPING SETS (
(region, department), -- 1. 지역별 & 부서별 집계
(region), -- 2. 지역별 소계
() -- 3. 전체 총계
);
-
위 예시는
GROUP BY ROLLUP(region, department)
와 동일한 결과를 보여줍니다. -
하지만
GROUPING SETS
를 사용하면ROLLUP
이나CUBE
로는 불가능한 조합을 만들 수 있습니다.
실전 활용 예시
‘지역별 소계’와 ‘부서별 소계’는 보고 싶지만, ‘지역+부서’의 상세 집계나 ‘전체 총계’는 필요 없다고 가정해 봅시다. GROUPING SETS
를 사용하면 이 요구사항을 완벽하게 만족시킬 수 있습니다.
SQL
SELECT region, department, SUM(amount)
FROM sales
GROUP BY GROUPING SETS (
(region), -- 지역별 소계만!
(department) -- 부서별 소계만!
);
결과 예시:
region | department | SUM(amount) |
---|---|---|
서울 | NULL | 3500 |
부산 | NULL | 3000 |
NULL | 영업1팀 | 2700 |
NULL | 영업2팀 | 3800 |
이처럼 GROUPING SETS
는 분석에 필요한 특정 관점의 집계 결과만 효율적으로 추출하고 싶을 때 사용하는 최고의 도구입니다.
7. 결론: 데이터를 요리하는 현명한 셰프가 되기 위한 비법
지금까지 우리는 데이터 분석의 효율을 극적으로 높여주는 ROLLUP
과 CUBE
에 대해 깊이 있게 탐험했습니다.
-
**
ROLLUP
**은 계층 구조를 따라 차근차근 보고서를 쌓아 올리는 성실한 분석가와 같습니다. 명확한 상하 관계가 있는 데이터를 분석할 때 최고의 선택입니다. -
**
CUBE
**는 모든 가능성을 탐색하며 데이터의 숨겨진 얼굴을 찾아내는 창의적인 탐험가와 같습니다. 여러 차원을 교차하여 다각적인 인사이트를 얻고 싶을 때 강력한 힘을 발휘합니다.
이 두 가지 강력한 도구를 언제 어떻게 사용해야 할지 이해하는 것은, 마치 셰프가 요리에 맞는 최고의 칼을 선택하는 것과 같습니다. 데이터의 특성과 분석의 목적을 명확히 이해하고 ROLLUP
과 CUBE
를 적재적소에 활용한다면, 여러분은 복잡한 데이터 속에서 가치 있는 인사이트를 빠르고 정확하게 찾아내는 ‘데이터 셰프’가 될 수 있을 것입니다.
단순히 데이터를 나열하는 것을 넘어, 소계와 총계를 통해 이야기의 흐름을 만들고, 다차원 분석으로 새로운 관점을 제시해 보세요. ROLLUP
과 CUBE
는 여러분의 데이터 분석 여정에 든든한 동반자가 되어줄 것입니다.