그룹함수
firststep 에디터
IT / 자격증 전문 라이터
그룹함수
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: 소계/총계 행에 라벨 붙여 가독성 개선
firststep 에디터 · IT / 자격증 전문 라이터
firststep.kr의 실무 에디터로서 무언가를 처음 도전하는 분들이 헤매지 않도록 검증된 지식과 실습 가이드를 작성합니다.
댓글 0개
댓글을 작성하려면 로그인이 필요합니다
간단한 이메일과 비밀번호로 3초 만에 가입하고 의견을 남겨보세요.
첫 번째 댓글을 남겨보세요!