반응형
그룹함수
반응형

1) 왜 ROLLUP / CUBE가 필요하나?
GROUP BY는 보통 “그룹별 합계”만 냅니다.
예) 부서+직무별 급여 합계
SELECT deptno, job, SUM(sal) total_salary
FROM emp
GROUP BY deptno, job;
그런데 실무/리포트에서는 보통 아래도 같이 필요합니다.
- 부서별 소계(부서 합계)
- 전체 합계(Grand Total)
이걸 한 번에 만들어 주는 게 ROLLUP / CUBE / GROUPING SETS 입니다.
2) ROLLUP: “계층적으로 소계 → 총계”
개념
ROLLUP(deptno, job)이면 집계가 이런 계층으로 나옵니다.
- (deptno, job) 상세 합계
- (deptno) 부서 소계
- (전체) 총계
예시
SELECT deptno, job, SUM(sal) total_salary
FROM emp
GROUP BY ROLLUP(deptno, job)
ORDER BY deptno, job;
결과에서 NULL의 의미(중요)
ROLLUP 결과에는 일부 행에서 deptno나 job이 NULL로 보이는데, 이게 “데이터가 없다”가 아니라 소계/총계 행이라는 뜻입니다.
- deptno=10, job=NULL → 10번 부서 소계
- deptno=NULL, job=NULL → 전체 총계
비유(성적표)
- 학생별 점수(상세)
- 반 평균(소계)
- 학년 평균(총계)
3) CUBE: “가능한 모든 조합의 소계/총계”
개념
CUBE(deptno, job)은 ROLLUP보다 더 많이 만듭니다.
- (deptno, job) 상세
- (deptno) 부서 소계
- (job) 직무 소계 ✅ ROLLUP에는 보통 없음
- (전체) 총계
예시
SELECT deptno, job, SUM(sal) total_salary
FROM emp
GROUP BY CUBE(deptno, job)
ORDER BY deptno, job;
핵심 차이
- ROLLUP: “왼쪽→오른쪽” 계층으로만 소계 생성
- CUBE: “부서 기준도, 직무 기준도” 모든 조합으로 생성
비유(매출)
- 지역+상품별 매출(상세)
- 지역별 매출(소계)
- 상품별 매출(소계)
- 전체 매출(총계)
4) GROUPING SETS: “내가 원하는 집계만 골라서”
개념
ROLLUP/CUBE는 정해진 규칙대로 집계를 만들어서 “필요 없는 소계”까지 나올 수 있습니다.
GROUPING SETS는 원하는 그룹만 직접 지정합니다.
예시(상세 + 부서소계 + 총계만 만들기)
SELECT deptno, job, SUM(sal) total_salary
FROM emp
GROUP BY GROUPING SETS (
(deptno, job), -- 상세
(deptno), -- 부서 소계
() -- 전체 총계
)
ORDER BY deptno, job;
5) GROUPING(): NULL이 “소계/총계용 NULL”인지 구분
ROLLUP/CUBE를 쓰면 NULL이 자주 나오니까,
GROUPING(컬럼)으로 이 NULL이 집계 때문에 생긴 건지를 판별합니다.
- GROUPING(deptno) 값이 1 → deptno가 “집계행 때문에” NULL (총계/직무소계 등)
- GROUPING(deptno) 값이 0 → deptno는 실제 그룹 컬럼으로 사용됨
예시(집계행 여부 확인 컬럼 추가)
SELECT
deptno, job,
SUM(sal) total_salary,
GROUPING(deptno) AS dept_group,
GROUPING(job) AS job_group
FROM emp
GROUP BY ROLLUP(deptno, job);
해석 예:
- dept_group=0, job_group=0 → (deptno, job) 상세행
- dept_group=0, job_group=1 → 부서 소계( job이 집계로 NULL )
- dept_group=1, job_group=1 → 전체 총계
6) CASE/DECODE로 “소계/총계 라벨” 붙이기 (가독성)
NULL만 보면 학생들이 헷갈립니다. 그래서 결과에 라벨 컬럼을 붙입니다.
CASE 예시(이미지 핵심)
SELECT
deptno, job,
SUM(sal) total_salary,
CASE
WHEN GROUPING(deptno)=1 AND GROUPING(job)=1 THEN 'TOTAL_SUM'
WHEN GROUPING(deptno)=0 AND GROUPING(job)=1 THEN 'DEPT_GROUPING'
WHEN GROUPING(deptno)=0 AND GROUPING(job)=0 THEN 'DEPT_JOB_GROUPING'
END AS grouping_level
FROM emp
GROUP BY ROLLUP(deptno, job)
ORDER BY deptno, job;
DECODE(오라클에서 CASE 대체)
이미지는 “CASE 대신 DECODE도 가능”을 보여줍니다.
보통 이런 식으로 GROUPING 값 조합을 하나로 만들어 매핑합니다.
한 줄 요약(시험용)
- ROLLUP: (왼→오) 계층 소계 + 총계
- CUBE: 가능한 모든 조합 소계 + 총계
- GROUPING SETS: 필요한 집계 조합만 선택
- GROUPING(): NULL이 “집계행 때문에 나온 NULL”인지 판별
- CASE/DECODE: 소계/총계 행에 라벨 붙여 가독성 개선
반응형
'sqld' 카테고리의 다른 글
| Top N 쿼리가 무엇인가요? (0) | 2026.02.25 |
|---|---|
| 윈도우함수가 무엇인가? (1) | 2026.02.25 |
| 집합연산자 (0) | 2026.02.24 |
| 서브쿼리 (0) | 2026.02.24 |
| JOIN 이해하기 (0) | 2026.02.23 |