2과목 · SQL 기본 및 활용·8장
집계 함수
COUNT/SUM/AVG/MIN/MAX의 NULL 처리, DISTINCT 사용, GROUP BY와의 관계를 정리합니다.
노란 밑줄 은 시험에 자주 나오는 지점✎ 는 덧붙인 필기
1. 집계 함수란
여러 행을 받아 하나의 결과를 돌려주는 함수. 단독으로 쓰면 전체 테이블을 1행으로 요약하고, GROUP BY와 함께 쓰면 그룹별로 1행씩 돌려줍니다.
2. 대표 함수
| 함수 | 설명 |
|---|---|
COUNT(*) |
모든 행 수 (NULL 포함) |
COUNT(col) |
col 이 NOT NULL 인 행 수 |
COUNT(DISTINCT col) |
중복 제거한 값의 수 |
SUM(col) |
합계 (NULL 무시) |
AVG(col) |
평균 (NULL 무시) |
MIN(col) / MAX(col) |
최솟값 / 최댓값 (NULL 무시) |
NULL 처리의 차이
COUNT(*)는 NULL도 센다.COUNT(col)은 col이 NULL인 행을 세지 않는다.SUM/AVG/MIN/MAX는 NULL을 무시하고 계산.
-- 10명 중 bonus가 3명에게만 값이 있을 때
SELECT COUNT(*), -- 10
COUNT(bonus), -- 3
AVG(bonus), -- 3명 평균 (10명 나눔 아님)
SUM(bonus) -- 3명 합
FROM emp;
3. GROUP BY와의 관계
SELECT에 등장하는 컬럼은 반드시 다음 중 하나:
GROUP BY에 나열된 컬럼- 집계 함수의 인자
-- ❌ 오류: name이 GROUP BY에도 없고 집계도 아님
SELECT dept_id, name, AVG(salary) FROM emp GROUP BY dept_id;
-- ✅
SELECT dept_id, AVG(salary) FROM emp GROUP BY dept_id;
4. DISTINCT와 함께
SELECT COUNT(DISTINCT dept_id) FROM emp; -- 고유 부서 수
SELECT AVG(DISTINCT salary) FROM emp; -- 중복 급여를 한 번씩 평균
5. 조건부 집계 (FILTER / CASE)
ANSI의 FILTER는 PostgreSQL 등이 지원, Oracle/MySQL은 CASE 패턴을 씁니다.
-- PostgreSQL
SELECT
COUNT(*) FILTER (WHERE salary >= 5000000) AS high_paid,
COUNT(*) FILTER (WHERE salary < 5000000) AS low_paid
FROM emp;
-- 범용: CASE + SUM/COUNT
SELECT
SUM(CASE WHEN salary >= 5000000 THEN 1 ELSE 0 END) AS high_paid,
SUM(CASE WHEN salary < 5000000 THEN 1 ELSE 0 END) AS low_paid
FROM emp;
6. HAVING — 집계 결과 필터
WHERE 에는 집계 함수를 쓸 수 없으니, 집계 후 필터는 HAVING 으로.
SELECT dept_id, COUNT(*) AS cnt
FROM emp
GROUP BY dept_id
HAVING COUNT(*) >= 5;
7. 집계와 인덱스
MIN(col)/MAX(col)은 col에 인덱스가 있으면 테이블 풀스캔 없이 빠르게 답.COUNT(*)전체 수는 테이블 크기가 크면 캐시된 통계를 쓰는 DBMS가 있음.
8. 자주 출제되는 포인트
COUNT(*)vsCOUNT(col)의 NULL 처리 차이.- SELECT에 들어가는 컬럼은 GROUP BY 포함 또는 집계 중 하나.
WHERE엔 집계 불가,HAVING엔 가능.AVG는 NULL을 무시하므로 분모가 전체 행수가 아님.DISTINCT를 결합해 고유값 기반 집계 가능.
9. 요약 체크리스트
- 다섯 가지 집계 함수의 NULL 처리 차이를 설명할 수 있다.
- GROUP BY와 SELECT의 규칙을 답할 수 있다.
- 조건부 집계를 CASE로 쓸 수 있다.
- WHERE vs HAVING의 사용 시점을 안다.