본문으로 건너뛰기
SQLD 준비실
이론 전체 목차 열기 11 / 32

SQL 기본 및 활용 · 집계와 정렬 11 / 32

GROUP BY, HAVING, ORDER BY 결과 읽기

집계 함수, 그룹화, 그룹 조건, 정렬이 결과 행 수와 표시 순서를 어떻게 바꾸는지 시험 풀이 순서로 정리합니다.

출제 빈도 ★★★★★ 관련 문제 10개 | GROUP BYHAVINGCOUNTROLLUPCUBE

집계 문제는 행 수 변화부터 봅니다

GROUP BY가 없는 SELECT는 보통 조건을 만족한 행을 그대로 보여줍니다. 하지만 GROUP BY가 있으면 여러 행이 그룹 단위로 묶이고, 결과 행 수가 그룹 수만큼 줄어듭니다.

SELECT deptno, COUNT(*) AS emp_count
FROM emp
GROUP BY deptno;

이 쿼리는 사원 한 명당 한 행이 아니라 부서 하나당 한 행을 반환합니다.

집계 함수의 NULL 처리

함수NULL 처리비고
COUNT(*)NULL 포함, 행 자체를 셉니다유일하게 NULL 포함
COUNT(컬럼)해당 컬럼이 NULL인 행 제외COUNT(*) - COUNT(col) = NULL 개수
COUNT(DISTINCT col)NULL 제외 + 중복 제거고유 값 개수
SUM(컬럼)NULL 제외전부 NULL이면 결과 NULL
AVG(컬럼)NULL 제외 후 평균분모도 NULL 제외한 개수
MAX, MINNULL 제외
-- COUNT(*) = 14, COUNT(comm) = 3 (comm 있는 사원만)
-- → NULL 인 comm 은 11개
SELECT COUNT(*), COUNT(comm), COUNT(*) - COUNT(comm) AS null_count
FROM emp;

SELECT 절에 올 수 있는 컬럼

GROUP BY를 사용하면 SELECT 절에는 다음 중 하나만 올 수 있습니다.

  • GROUP BY에 적은 컬럼 (또는 그 표현식)
  • 집계 함수로 감싼 표현식
  • 상수
-- ✗ 잘못된 예: job 이 그룹 기준도 집계도 아님
SELECT deptno, job, COUNT(*)
FROM emp
GROUP BY deptno;

위 쿼리는 job이 그룹 기준도 집계 함수도 아니므로 오류가 발생합니다. 부서별로 여러 직무가 있을 수 있어 DBMS가 어떤 job을 보여줘야 할지 결정할 수 없기 때문입니다.

WHERE와 HAVING 차이

WHERE

  • 개별 행을 먼저 거름
  • GROUP BY 이전 단계에서 평가
  • 집계 함수 사용 불가
  • 인덱스 활용 가능
WHERE sal >= 1000

HAVING

  • 그룹화된 결과를 거름
  • GROUP BY 이후 단계에서 평가
  • 집계 함수 사용 가능
  • 인덱스 활용 X (이미 집계된 결과)
HAVING AVG(sal) >= 2000
SELECT deptno, AVG(sal) AS avg_sal
FROM emp
WHERE job <> 'PRESIDENT'
GROUP BY deptno
HAVING AVG(sal) >= 2000;

WHERE는 사장 행을 먼저 제거하고, HAVING은 부서별 평균을 계산한 뒤 그룹을 제거합니다. 개별 행 조건은 WHERE에 두어야 처리 대상이 줄어들어 성능에 유리합니다.

ORDER BY

ORDER BY는 최종 결과의 표시 순서를 정합니다.

SELECT deptno, COUNT(*) AS emp_count
FROM emp
GROUP BY deptno
ORDER BY emp_count DESC, deptno ASC;

정렬 기준이 여러 개이면 앞 기준이 같을 때 다음 기준을 사용합니다. 위 쿼리는 사원 수가 많은 부서가 먼저 나오고, 사원 수가 같으면 부서번호가 작은 순서로 표시됩니다.

GROUP BY 확장: ROLLUP · CUBE · GROUPING SETS

함수결과 조합 수 (컬럼 n개)용도
GROUP BY ROLLUP(a, b)n + 1 = 3개: (a,b), (a), ()계층적 소계 (왼→오)
GROUP BY CUBE(a, b)2^n = 4개: (a,b), (a), (b), ()모든 조합 소계
GROUPING SETS((a,b),(b))명시한 개수만원하는 조합만

GROUPING(col) 함수는 결과 행이 해당 컬럼의 소계 행인지(1) 아닌지(0)를 알려줍니다. NULL과 소계-NULL을 구별할 때 사용합니다.

시험 풀이 순서

SELECT 논리 실행 순서

  1. 1
    FROM — 테이블 결합
  2. 2
    WHERE — 개별 행 필터
  3. 3
    GROUP BY — 행을 그룹으로
  4. 4
    HAVING — 그룹 필터
  5. 5
    SELECT — 컬럼 선택 + 별칭
  6. 6
    ORDER BY — 결과 정렬

작성 순서는 SELECT → FROM → WHERE … 이지만 평가는 FROM부터 시작합니다.

WHERE는 행을 줄이고, GROUP BY는 행을 묶고, HAVING은 묶인 결과를 다시 거릅니다.