집계함수는 여러 행(row)의 값을 모아서 하나의 값으로 계산하는 함수이다.
주로 GROUP BY와 함께 사용하며, “부서별/지역별/상품별 통계” 같은 요약 결과를 만들 때 사용한다.
대표적인 집계함수는 다음과 같다.
COUNT(*) : 행의 개수를 센다.COUNT(col) : NULL이 아닌 값의 개수를 센다.SUM(col) : 합계를 구한다. (숫자 컬럼)AVG(col) : 평균을 구한다. (숫자 컬럼)MAX(col) : 최댓값을 구한다.MIN(col) : 최솟값을 구한다.예시) 부서별 인원 수
SELECT dept, COUNT(*) AS cnt
FROM emp
GROUP BY dept;
주의) 집계함수와 함께 일반 컬럼을 출력하려면, 그 컬럼은 GROUP BY에 포함되어야 한다.
-- ❌ 오류 가능: name은 그룹 기준이 아니라 그룹(부서) 내에 여러 값이 존재할 수 있음
SELECT dept, name, COUNT(*)
FROM emp
GROUP BY dept;
-- ✅ 가능: dept+name 조합으로 그룹을 만들면 name도 한 그룹당 1개로 확정됨
SELECT dept, name, COUNT(*)
FROM emp
GROUP BY dept, name;
WHERE 절은 행(row) 단위 조건을 적용하여 데이터를 미리 걸러내는 절이다.
즉, GROUP BY로 묶기 전에 “어떤 행을 대상으로 집계/조회할지”를 결정한다.
WHERE에는 일반 컬럼 조건을 자유롭게 쓸 수 있다.WHERE에는 보통 집계함수(COUNT, SUM 등)를 쓸 수 없다. (집계 전 단계라서)예시) 개발팀만 먼저 필터링한 뒤 부서별 인원 집계
SELECT dept, COUNT(*) AS cnt
FROM emp
WHERE dept = '개발팀'
GROUP BY dept;
GROUP BY 절은 특정 컬럼을 기준으로 여러 행을 묶어 그룹(group) 을 만드는 절이다.
그룹별로 집계함수를 적용해 “요약 결과”를 만들 때 사용한다.
GROUP BY dept라면 결과는 부서당 1행이 된다.SELECT에는 다음만 올 수 있다.GROUP BY에 포함된 컬럼예시) 부서별 평균 급여
SELECT dept, AVG(salary) AS avg_salary
FROM emp
GROUP BY dept;
잘못된 예시
-- ❌ name은 같은 dept 안에 여러 값이 있어서, 그룹 결과 1행에 무엇을 넣을지 결정 불가
SELECT dept, name, COUNT(*)
FROM emp
GROUP BY dept;
HAVING 절은 그룹(group) 단위 조건을 적용하는 절이다.
즉, GROUP BY로 그룹을 만든 뒤 “어떤 그룹만 남길지” 필터링한다.
HAVING에는 보통 다음만 쓸 수 있다.GROUP BY에 쓴 컬럼COUNT, SUM, AVG 등)GROUP BY에 없는 일반 컬럼을 HAVING에 쓰면 오류가 날 수 있다.예시) 부서별 인원 수 중 3명 이상인 부서만
SELECT dept, COUNT(*) AS cnt
FROM emp
GROUP BY dept
HAVING COUNT(*) >= 3;
예시) GROUP BY에 쓴 컬럼으로 HAVING 조건
SELECT dept, COUNT(*) AS cnt
FROM emp
GROUP BY dept
HAVING dept <> '인턴팀';
오류 예시
-- ❌ name은 그룹 기준도 아니고 집계값도 아니라 그룹 결과에서 확정 불가
SELECT dept, COUNT(*)
FROM emp
GROUP BY dept
HAVING name = 'Kim';
일반적으로 다음 순서로 처리된다고 이해하면 된다.
FROM → WHERE → GROUP BY → HAVING → SELECT
WHERE: 행 필터(집계 전)HAVING: 그룹 필터(집계 후)SELECT가 논리적으로 GROUP BY 뒤에 처리되기 때문에, 이미 데이터가 “그룹 단위”로 바뀐 상태.
그래서 SELECT에서는 그룹 기준 컬럼이나 집계값만 안전하게 꺼낼 수 있음