GROUP BY·HAVING 완벽 정리

집계함수, ROLLUP, CUBE, GROUPING SETS까지 한눈에 정리

1. 집계 함수 (Aggregate Functions)

주요 집계 함수

함수설명NULL 처리
COUNT(*)전체 행 수NULL 포함
COUNT(col)해당 컬럼의 NULL 아닌 행 수NULL 제외
COUNT(DISTINCT col)중복 제거 후 행 수NULL 제외
SUM(col)합계NULL 제외
AVG(col)평균 (NULL 행 제외 후 계산)NULL 제외
MAX(col)최댓값NULL 제외
MIN(col)최솟값NULL 제외

NULL 처리 핵심

집계 함수는 기본적으로 NULL을 무시한다. 단, COUNT(*)만 유일하게 NULL을 포함하여 전체 행 수를 센다. AVG 계산 시 NULL 행은 분모에서도 제외된다.

COUNT 비교 예시

데이터: 부서(A, A, B, NULL, B)

함수결과이유
COUNT(*)5NULL 포함 전체 행
COUNT(부서)4NULL 1건 제외
COUNT(DISTINCT 부서)2NULL 제외 + 중복 제거 (A, B)

2. GROUP BY 기본

GROUP BY 규칙

SELECT절에서 집계함수가 아닌 컬럼은 반드시 GROUP BY에 포함해야 한다. 이를 위반하면 SQL 오류가 발생한다.

-- 올바른 예

SELECT 부서, COUNT(*) FROM 사원 GROUP BY 부서;

-- 오류 (이름이 GROUP BY에 없음)

SELECT 부서, 이름, COUNT(*) FROM 사원 GROUP BY 부서;

SQL 실행 순서

GROUP BY를 이해하려면 SQL 실행 순서를 반드시 알아야 한다.

순서설명
1FROM테이블 접근
2WHERE행 필터링 (그룹화 전)
3GROUP BY그룹화
4HAVING그룹 필터링 (그룹화 후)
5SELECT컬럼 선택, 집계 계산
6ORDER BY정렬

3. HAVING절

HAVING이란?

GROUP BY로 그룹화된 결과에 조건을 적용하여 필터링하는 절. 집계 함수를 조건으로 사용할 수 있다.

WHERE vs HAVING

구분WHEREHAVING
실행 시점그룹화 전 (FROM 다음)그룹화 후 (GROUP BY 다음)
집계함수사용 불가사용 가능
필터 대상개별 행그룹(집계 결과)
예시WHERE 급여 > 3000HAVING COUNT(*) > 5

실전 SQL 예시

-- 부서별 인원이 5명 이상인 부서만 조회

SELECT 부서, COUNT(*) AS 인원

FROM 사원

WHERE 퇴사여부 = 'N'

GROUP BY 부서

HAVING COUNT(*) >= 5

ORDER BY 인원 DESC;

WHERE로 퇴사자 제외(행 필터) → GROUP BY로 부서별 그룹화 → HAVING으로 5명 이상만 필터

4. 고급 그룹 함수

ROLLUP

지정된 컬럼의 소계와 총계를 자동 생성한다. 인수 순서가 중요하며, 계층적으로 집계된다.

GROUP BY ROLLUP(부서, 직급)

-- 결과: (부서,직급) + (부서) 소계 + 총계

ROLLUP(A, B)의 결과 행: (A,B) 그룹 + (A) 소계 + () 총계 → N+1개 레벨의 소계 생성 (인수가 N개일 때)

CUBE

지정된 컬럼의 모든 조합에 대한 소계를 생성한다. 인수 순서와 무관하게 동일한 결과를 반환한다.

GROUP BY CUBE(부서, 직급)

-- 결과: (부서,직급) + (부서) + (직급) + 총계

CUBE(A, B)의 결과 행: (A,B) + (A) + (B) + () → 2^N개 레벨의 소계 생성 (인수가 N개일 때)

GROUPING SETS

특정 그룹만 선택적으로 집계할 수 있다. ROLLUP, CUBE와 달리 원하는 조합만 명시한다.

GROUP BY GROUPING SETS(부서, 직급)

-- 결과: (부서) 소계 + (직급) 소계만 생성

-- (부서,직급) 조합이나 총계는 생성되지 않음

GROUPING() 함수

소계/총계 행과 원본 데이터 행을 구분하는 함수.

반환값의미
0해당 컬럼이 그룹화에 사용됨 (원본 데이터)
1해당 컬럼이 집계에 의해 NULL됨 (소계/총계 행)

SELECT

CASE WHEN GROUPING(부서) = 1 THEN '전체'

ELSE 부서 END AS 부서,

COUNT(*) AS 인원

FROM 사원

GROUP BY ROLLUP(부서);

5. ROLLUP vs CUBE vs GROUPING SETS 비교

핵심 비교 테이블

구분ROLLUPCUBEGROUPING SETS
소계 범위계층적 소계 + 총계모든 조합의 소계 + 총계명시한 조합만
인수 순서중요 (결과 달라짐)무관 (결과 동일)무관
소계 레벨 수N+12^N명시한 수만큼
총계자동 포함자동 포함() 명시해야 포함

ROLLUP(A,B) vs CUBE(A,B) 결과 행 비교

그룹 조합ROLLUPCUBE
(A, B)OO
(A) 소계OO
(B) 소계XO
() 총계OO

ROLLUP(A,B)은 (B)만의 소계를 생성하지 않는다. CUBE는 모든 조합을 생성하므로 (B) 소계도 포함.

6. 시험 빈출 포인트

자주 출제되는 유형

  • SELECT절 집계함수 규칙 — 집계함수 아닌 컬럼은 반드시 GROUP BY에 포함
  • HAVING vs WHERE 차이 — WHERE는 그룹화 전, HAVING은 그룹화 후 필터링
  • COUNT(*) vs COUNT(col) — NULL 포함 여부가 핵심 차이
  • ROLLUP 결과 행 수 계산 — 인수 N개일 때 N+1 레벨의 소계
  • ROLLUP 인수 순서 — ROLLUP(A,B)와 ROLLUP(B,A)는 결과가 다름
  • GROUPING() 함수 반환값 — 0은 원본, 1은 소계/총계 행
  • SQL 실행 순서 — FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY

개념을 확인했다면 문제로 실력을 검증해보세요