데이터를 그룹으로 묶어 합계·평균·개수를 구하는 방법.
집계 함수와 GROUP BY · HAVING
"부서별 평균 급여", "월별 매출 합계"처럼 여러 행을 하나의 값으로 요약하는 것이 집계입니다. 집계 함수와 GROUP BY 를 익히면 데이터에서 의미 있는 통계를 뽑아낼 수 있습니다.
학습 목표
- COUNT·SUM·AVG·MIN·MAX 집계 함수를 사용합니다.
GROUP BY로 행을 그룹으로 묶습니다.WHERE와HAVING의 차이를 이해합니다.- 집계 시
NULL이 어떻게 처리되는지 파악합니다.
집계 함수
| 함수 | 설명 |
|---|---|
COUNT(*) | 행의 개수 |
COUNT(col) | col 이 NULL이 아닌 행의 개수 |
SUM(col) | 합계 |
AVG(col) | 평균 |
MIN(col) / MAX(col) | 최솟값 / 최댓값 |
SELECT
COUNT(*) AS 직원수,
SUM(salary) AS 급여총합,
AVG(salary) AS 평균급여,
MIN(salary) AS 최저급여,
MAX(salary) AS 최고급여
FROM Employees;
전체를 하나로 요약할 때는 GROUP BY 없이 집계 함수만 써도 됩니다.
GROUP BY — 그룹으로 묶기
SELECT department, COUNT(*) AS 인원, AVG(salary) AS 평균급여
FROM Employees
GROUP BY department;
| department | 인원 | 평균급여 |
|---|---|---|
| Sales | 12 | 3,200,000 |
| Dev | 8 | 4,100,000 |
⚠️ 주의 —
SELECT절에 집계하지 않은 열을 쓰려면 반드시GROUP BY에 포함해야 합니다.GROUP BY department인데SELECT name을 하면 오류가 납니다.
여러 열로도 그룹을 만들 수 있습니다.
SELECT department, job_title, COUNT(*) AS 인원
FROM Employees
GROUP BY department, job_title;
HAVING vs WHERE
WHERE는 그룹으로 묶기 전 개별 행을 거릅니다.HAVING은 그룹으로 묶은 후 집계 결과를 거릅니다.
-- 재직 중인 직원만 대상으로, 평균급여가 350만 원 넘는 부서
SELECT department, AVG(salary) AS 평균급여
FROM Employees
WHERE status = 'active' -- 행 필터 (집계 전)
GROUP BY department
HAVING AVG(salary) > 3500000; -- 그룹 필터 (집계 후)
실행 순서를 기억하면 헷갈리지 않습니다.
FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY
💡 TIP —
WHERE절에는 집계 함수를 쓸 수 없습니다.WHERE AVG(salary) > 3500000은 오류이고, 이런 조건은HAVING으로 보내야 합니다.
NULL 처리
집계 함수는 대부분 NULL 을 무시합니다.
-- bonus 가 NULL 인 행은 SUM/AVG 계산에서 제외됨
SELECT AVG(bonus) FROM Employees;
-- NULL 을 0 으로 취급하고 싶다면 ISNULL/COALESCE
SELECT AVG(ISNULL(bonus, 0)) FROM Employees;
| 함수 | NULL 취급 |
|---|---|
COUNT(*) | NULL 포함해서 셈 |
COUNT(col) | NULL 제외하고 셈 |
SUM/AVG/MIN/MAX | NULL 무시 |
따라서 AVG(bonus) 는 "보너스를 받는 사람들의 평균"이 됩니다. 전체 직원 기준 평균을 원하면 ISNULL 로 0을 채워야 결과가 달라진다는 점에 유의하세요.
요약
- 집계 함수(COUNT·SUM·AVG·MIN·MAX)는 여러 행을 한 값으로 요약합니다.
GROUP BY로 묶으면 그룹마다 집계 결과가 나옵니다.SELECT의 비집계 열은GROUP BY에 포함해야 합니다.WHERE는 집계 전 행,HAVING은 집계 후 그룹을 거릅니다.- 대부분의 집계 함수는
NULL을 무시하므로 필요하면ISNULL로 채웁니다.
연습문제
- 부서별 직원 수와 최고 급여를 함께 출력하세요.
- 직원 수가 5명을 초과하는 부서만 골라 보세요.
- 재직 중(
status = 'active')인 직원만 대상으로 부서별 평균 급여를 구하세요. - 보너스를 받지 않은 직원을 0으로 간주한 전체 평균 보너스를 구하세요.
힌트 — 2번은
HAVING COUNT(*) > 5, 4번은AVG(ISNULL(bonus, 0))을 사용합니다.
💡 연습문제 풀이
불러오는 중…
댓글 0
“MSSQL” 강좌에 대한 댓글입니다.