ORACLE의 그룹 함수인 ROLLUP, CUBE, GROUPING SETS, GROUPING에 대해 알아보려고 합니다!
부분별 또는 전체 총계를 구해주는 함수입니다.
간단한 예제를 통해 알아보겠습니다.
emp table
사원 정보가 저장되어 있는 emp 테이블에서 부서별 인원수와 급여 총계를 구해보겠습니다.
select deptno 부서, count(*) 인원수, sum(sal) 급여총계
from emp
group by rollup(deptno)
order by 1;

10, 20, 30번 부서에 대한 인원수와 급여총계를 구한 뒤, 마지막에 전체 인원수와 급여총계를 구하는 것을 볼 수 있습니다.
❗
ROLLUP 함수는 여러 조건을 나열할 수 있는데(ROLLUP(조건1, 조건2, ...)) 조건의 순서가 바뀌면 결과값도 바뀌게 됩니다.
select deptno, job, count(*)
from emp
group by rollup(deptno, job)
order by deptno;

select job, deptno, count(*)
from emp
group by rollup(job, deptno)
order by 1;

1번은 부분별 총계가 부서에 대한 총 인원수로 나옵니다.
2번은 부분별 총계가 직업에 대한 총 인원수로 나옵니다.
이처럼 조건 순서에 따라 결과값이 달라집니다.
모든 경우의 수에 대한 부분별 총계와 전체 총계를 구해주는 함수입니다.
예제를 통해 알아보도록 하겠습니다.
부서 + 직업이 같은 사원, 부서별, 직업별, 사원 전체의 사원 수와 급여 총계를 구해주는 예제입니다.
select deptno, job, count(*), sum(sal)
from emp
group by cube(deptno, job)
order by 1;

❗
CUBE 함수는 조건의 순서가 바뀌어도 결과가 바뀌지 않습니다. (모든 경우의 수에 대한 결과값을 내기 때문에)
위 예제에서 조건의 순서만 바꾼 쿼리문입니다.
select deptno, job, count(*), sum(sal)
from emp
group by cube(job, deptno)
order by 1;

grouping sets(조건1, 조건2, ...)select deptno, job, count(*)
from emp
group by grouping sets(deptno, job)
order by 1;

grouping sets((조건1, 조건2), 조건3)select deptno, job, mgr, count(*), sum(sal)
from emp
where mgr is not null
group by grouping sets((deptno, job), mgr)
order by 1;

grouping sets(조건1, null)select deptno, job, count(*), sum(sal)
from emp
-- (deptno, job)으로 각각 그룹핑 후 전체 결과를 출력
group by grouping sets((deptno, job), null)
order by 1;

GROUPING 함수는 NULL인 경우 1을 리턴하고 NULL이 아닌 경우 0을 리턴합니다.
주의 실데이터의 null은 0으로 리턴합니다.
총계를 내며 생성된 행의 null만 1로 리턴됩니다.
player_t table
select player_name, position from player_t;
포지션 별 선수 인원과 전체 선수 인원을 구하시오
select position, count(*) 선수인원
from player_t
group by rollup(position);

여기서 8행의 null은 position이 정해지지 않은 선수입니다. 3명이 있는 것을 확인할 수 있습니다.
9행의 null은 전체 선수 인원 총계를 구하며 생성된 null입니다.
따라서 grouping(position)을 진행할 경우 9행의 null만 1을 리턴하게 됩니다.

포지션 별 선수 인원과 전체 선수 인원을 구하시오.
(단, 포지션이 정해지지 않은 선수는 '미정'으로 표시하고 전체 선수는 '전체총계'로 출력하시오.)
select case
when grouping(position) = 1 then '전체총계'
else nvl(position, '미정')
end 포지션, count(*) 선수인원
from player_t
group by rollup(position);

어려운 부분이라 아직 완벽하게 이해하지 못한 상태입니다 ㅠㅠ 따라서 글도 이해하기 어렵게 작성한 것 같습니다 😥 만약 잘못된 부분이 있다면 댓글로 알려주시면 감사하겠습니다.
읽어주셔서 감사합니다!