우와한 개발자

[SQL] 그룹 함수 - GROUP BY와 HAVING절, GROUPING SET, ROLLUP, CUBE, GROUPING, GROUPING ID

by 우와한개발자

1. GROUP BY절 : 그룹화

  • 테이블의 행을 특정 기준으로 묶어서 집계
  • SELECT에 있는 컬럼 중 집계함수가 아닌 컬럼은 반드시 GROUP BY에 포함.
    • GROUP BY는 여러 행을 하나로 줄이기 때문에, 값이 여러 개 나오는 컬럼은 SELECT에 그대로 쓸 수 없기 때문
SELECT column, 집계함수
FROM table
GROUP BY column;
--SQL Error: ORA-00979: not a GROUP BY expression 오류 발생
SELECT DEPTNO, ENAME, AVG(SAL) -- 컬럼, 컬럼, 그룹함수
FROM EMP
GROUP BY DEPTNO; --SELECT절에서 그룹함수가 아닌 컬럼은 GROUP BY절에 포함되어야 함

 

2. HAVING절 : 그룹 조건

  • GROUP BY 결과에 조건을 적용
SELECT column, 집계함수
FROM table
GROUP BY column
HAVING 조건;
SELECT department_id,
       AVG(salary)
FROM employees
GROUP BY department_id
HAVING AVG(salary) >= 5000;

 

❓ WHERE vs HAVING
구분 대상
WHERE 그룹화 전
WHERE 그룹화 후

 

3. GROUPING SET

  • 여러 GROUP BY를 한 번에 수행
SELECT department_id,
       job_id,
       SUM(salary)
FROM employees
GROUP BY GROUPING SETS (
    (department_id, job_id),
    (department_id),
    ()
);

 

4. ROLLUP

  • 지정한 컬럼의 계층적 소계와 총계 생성
  • 즉, 지정한 컬럼 순서대로 계층을 만들고, 오른쪽부터 접어가면서 소계를 만들어 생성
SELECT department_id,
       job_id,
       SUM(salary)
FROM employees
GROUP BY ROLLUP(department_id, job_id);
  • 그룹화 순서(오른쪽부터 하나씩 제거됨)
단계 의미
1 (department_id, job_id) → 상세
2 (department_id) → 부서별 합계
3 () → 전체 합계

 

5. CUBE

  • 지정한 컬럼의 모든 가능한 조합으로 소계를 생성
  • ROLLUP보다 많이 생성
SELECT department_id,
       job_id,
       SUM(salary)
FROM employees
GROUP BY CUBE(department_id, job_id);

 

6. GROUPING

  • 해당 컬럼이 집계로 인해 NULL인지 확인
SELECT department_id,
       job_id,
       GROUPING(department_id) AS g1,
       GROUPING(job_id) AS g2
FROM employees
GROUP BY ROLLUP(department_id, job_id);

 

7. GROUPING ID

  • 여러 컬럼의 GROUPING 결과를 2진수 비트로 합산한 숫자
  • GROUPING(col1) × 2 + GROUPING(col2) 방식으로 계산
  • 숫자가 클수록 더 높은 단계의 집계(소계 → 총계)
SELECT department_id,
       job_id,
       SUM(salary),
       GROUPING(department_id)            AS g_dept,
       GROUPING(job_id)                   AS g_job
FROM employees
GROUP BY ROLLUP(department_id, job_id);
department_id job_id SUM(salary) g_dept g_job 설명
10 IT_PROG 5000 0 0 일반 행
10 NULL 5000 0 1 부서 소계
NULL NULL 12000 1 1 전체 총계
SELECT department_id,
       job_id,
       SUM(salary),
       GROUPING_ID(department_id, job_id) AS gid
FROM employees
GROUP BY ROLLUP(department_id, job_id);
department_id job_id SUM(salary) gid 비트 해석 설명
10 IT_PROG 5000 0 00 일반 행
10 NULL 5000 1 01 job 기준 집계 (부서 소계)
NULL NULL 12000 3 11 전체 총계

 

1) 비트 의미

비트값 department_id job_id 의미
0 실제 값 존재 실제 값 존재 집계 아님
1 소계용 NULL 소계용 NULL ROLLUP/CUBE가 만든 NULL

 

2) GROUPING_ID 계산 방법 : 2진수

department_id 비트 job_id 비트 계산식 GROUPING_ID
0 0 0×2 + 0 0 (00)
0 1 0×2 + 1 1 (01)
1 1 1×2 + 1 3 (11)

 

블로그의 정보

우와한개발자 님의 블로그

우와한개발자

활동하기