이 글의 핵심
WHERE는 그룹화 전의 행을, HAVING은 만들어진 그룹을 필터링합니다.
GROUP BY 이후 SELECT에는 그룹 기준 열이나 집계 표현식을 사용해야 합니다.
COUNT(*)와 COUNT(열)은 NULL 포함 여부가 다릅니다.
WHERE와 HAVING은 필터 대상이 다르다
WHERE는 개별 행을 대상으로 하며 GROUP BY보다 먼저 실행됩니다. HAVING은 GROUP BY로 생성된 그룹을 대상으로 하므로 SUM, COUNT 같은 집계 결과를 조건에 사용할 수 있습니다.
“2026년 주문만 모아 고객별 합계를 구한 뒤 합계가 100만 원 이상인 고객”을 찾는다면 연도 조건은 WHERE, 합계 조건은 HAVING에 둡니다.
SELECT customer_id, SUM(amount) AS total_amount
FROM orders
WHERE order_date >= DATE '2026-01-01'
GROUP BY customer_id
HAVING SUM(amount) >= 1000000;논리적 실행 순서로 오류 찾기
SQL을 작성하는 순서와 논리적으로 처리되는 순서는 다릅니다. SELECT에서 만든 별칭을 WHERE에서 바로 사용할 수 없는 이유도 WHERE가 SELECT보다 먼저 처리되기 때문입니다.
FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BYGROUP BY 이후 행의 의미가 바뀐다
GROUP BY 전에는 한 행이 주문 한 건을 의미하지만, 고객별 GROUP BY 후에는 한 행이 고객 한 명의 주문 묶음을 의미합니다. 따라서 SELECT에는 customer_id처럼 그룹을 대표하는 열이나 SUM(amount)처럼 그룹 전체를 계산한 값이 와야 합니다.
그룹에 포함되지 않은 일반 열을 SELECT에 그대로 쓰면 어떤 행의 값을 보여줘야 할지 결정할 수 없습니다. DBMS 설정에 따라 오류가 나거나 비결정적인 결과를 만들 수 있으므로 시험에서는 잘못된 문장으로 판단합니다.
COUNT와 NULL을 함께 확인하기
COUNT(*)는 그룹의 모든 행을 세지만 COUNT(column)은 해당 열이 NULL이 아닌 행만 셉니다. COUNT(DISTINCT column)은 NULL을 제외하고 서로 다른 값의 개수를 셉니다.
| 표현식 | 세는 대상 |
|---|---|
| COUNT(*) | 모든 행 |
| COUNT(score) | score가 NULL이 아닌 행 |
| COUNT(DISTINCT score) | NULL을 제외한 서로 다른 score 값 |
집계 문제 점검표
결과를 계산하기 전에 WHERE로 제거되는 행에 선을 긋고, 남은 행을 GROUP BY 값별로 묶으세요. 각 묶음에서 집계값을 계산한 다음 HAVING을 적용하면 실수가 줄어듭니다.
- 집계 전 필터인가, 집계 후 필터인가?
- NULL이 집계에 포함되는가?
- GROUP BY 열 조합이 실제 몇 개의 그룹을 만드는가?
- DISTINCT가 행 전체인지 특정 집계 인수에 적용되는지 확인했는가?
자체 제작 사례: 부서별 평균 급여 조건을 WHERE와 HAVING으로 분리하기
재직 중인 직원만 대상으로 부서별 평균 급여가 400만 원 이상인 부서를 찾는다고 가정합니다.
- 재직 여부처럼 개별 행에 적용되는 조건을 WHERE에 둡니다.
- 부서 코드를 GROUP BY에 두고 AVG로 그룹별 값을 계산합니다.
- 평균 급여처럼 집계 결과에 적용되는 조건을 HAVING에 둡니다.
조건이 원본 행을 거르는지, 그룹 계산 결과를 거르는지 질문하면 WHERE와 HAVING을 구분할 수 있습니다.
흔한 오답 사고 바로잡기
집계 함수가 포함된 모든 조건은 HAVING에 작성한다.
왜 틀리는가: 집계 전에 제거할 행까지 그룹에 포함되면 평균·합계의 입력 자체가 달라져 의도와 다른 결과가 나옵니다.
올바른 확인법: 원본 행 조건은 WHERE, 그룹 결과 조건은 HAVING으로 분리하고 논리적 처리 순서에 맞춰 확인합니다.
복습 체크리스트
SELECT의 비집계 열이 GROUP BY에 포함되는지 확인
WHERE가 집계 입력 행을 올바르게 제한하는지 확인
HAVING 조건의 단위가 그룹인지 확인
NULL이 집계 함수에 미치는 영향 계산
자주 묻는 질문
GROUP BY 없이 HAVING을 사용할 수 있나요?
DBMS에 따라 전체 결과를 하나의 그룹으로 보고 사용할 수 있습니다. 다만 SQLD 문제에서는 구문과 DBMS별 동작 조건을 함께 확인해야 합니다.
ORDER BY에서 SELECT 별칭을 사용할 수 있는 이유는 무엇인가요?
논리적 처리 순서에서 ORDER BY가 SELECT 이후에 평가되므로 SELECT에서 정한 별칭을 참조할 수 있습니다.
검수 기준과 공식 자료
이 글은 가풀이 직접 작성·검수했으며 실제 기출문제나 복원문제를 옮기지 않았습니다. 시험 일정과 세부 규정은 변경될 수 있으므로 접수 전 아래 공식 공고를 다시 확인하세요.
- SQL 개발자 자격시험 공식 안내 — 한국데이터산업진흥원 데이터자격시험