본문 바로가기
프로그래밍/MySQL

📊 [SQL 프로젝트] 제17장 HAVING - 그룹을 만든 후 조건 선택하기

by 강릉바다의 블로그 2026. 7. 1.

제17장 HAVING - 그룹을 만든 후 조건 선택하기

오늘의 질문

지난 시간에는 GROUP BY를 이용하여 국가별 고객 수를 계산했습니다.

Germany   11명
France     9명
Brazil     9명
UK          7명
...

그런데 사장님이 다시 말합니다.

"고객이 많은 국가만 보고 싶습니다."

 

이번에는 모든 국가가 아니라

고객이 5명 이상인 국가만

출력해야 합니다.

이럴 때 사용하는 명령어가 바로 HAVING입니다.


학습 목표

이번 장을 학습하면 다음 내용을 할 수 있습니다.

  • HAVING의 역할을 설명할 수 있다.
  • GROUP BY와 HAVING를 함께 사용할 수 있다.
  • WHERE와 HAVING의 차이를 설명할 수 있다.
  • 그룹을 만든 후 원하는 그룹만 선택할 수 있다.

17-1. HAVING이란 무엇일까요?

지난 장에서 배운 것처럼

GROUP BY는 같은 값을 가진 행을 하나의 그룹으로 묶습니다.

하지만 그룹이 만들어졌다고 해서

항상 모든 그룹을 출력할 필요는 없습니다.

예를 들어

Germany   11명
France     9명
Brazil     9명
UK          7명
Mexico      5명
Norway      1명

이 중에서

고객이 5명 이상인 국가만

보고 싶을 수도 있습니다.

이처럼

그룹을 만든 후 조건을 적용하는 명령어가 HAVING입니다.


🤔 WHERE로는 안 될까요?

많은 학생들이 가장 먼저 하는 질문입니다.

"WHERE를 사용하면 안 되나요?"

 

정답은 안 됩니다.

왜냐하면 WHERE는 그룹을 만들기 전에 조건을 검사하기 때문입니다.

반면 HAVING그룹이 만들어진 후 조건을 검사합니다.


교실에서 생각해 봅시다

학생 30명이 있습니다.

먼저

남학생만 앞으로 나오세요.

라고 하면 이것은 WHERE 입니다.

학생을 먼저 선택한 것입니다.


그다음 선택된 학생들을

1모둠
2모둠
3모둠

으로 나눕니다.

이것이 GROUP BY 입니다.


마지막으로

5명 이상인 모둠만 발표하세요.

라고 하면 이미 만들어진 모둠을 선택한 것입니다.

이것이 HAVING입니다.


SQL 처리 순서를 이해해 봅시다.

SQL은 다음과 같은 순서로 동작합니다.

FROM
↓
WHERE
↓
GROUP BY
↓
HAVING
↓
SELECT
↓
ORDER BY

즉,

그룹이 만들어지기 전에는 HAVING을 사용할 수 없고,

그룹이 만들어진 후에는 WHERE 대신 HAVING을 사용합니다.


17-2. 먼저 실행해 봅시다.

SELECT Country,
       COUNT(*) AS CustomerCount
FROM Customers
GROUP BY Country
HAVING COUNT(*) >= 5;

실행 결과(예)

Country CustomerCount
Germany 11
France 9
Brazil 9
UK 7
Mexico 5

고객이 5명 이상인 국가만 출력되었습니다.


SQL을 한 줄씩 읽어 보기

SELECT Country,
       COUNT(*) AS CustomerCount
FROM Customers
GROUP BY Country
HAVING COUNT(*) >= 5;
SELECT Country

국가를 출력합니다.

COUNT(*)

국가별 고객 수를 계산합니다.

FROM Customers

Customers 테이블에서 데이터를 가져옵니다.

GROUP BY Country

같은 국가끼리 묶습니다.

HAVING COUNT(*) >= 5

고객 수가 5명 이상인 그룹만 선택합니다.


17-3. WHERE와 HAVING 비교

구분 WHERE HAVING
조건 적용 대상 개별 행(Row) 그룹(Group)
실행 시점 그룹 만들기 전 그룹 만든 후
집계 함수 사용 사용할 수 없음 사용할 수 있음
함께 사용하는 문법 SELECT GROUP BY

예제를 비교해 봅시다.

WHERE 사용

SELECT *
FROM Customers
WHERE Country = 'Germany';

독일 고객만 먼저 선택합니다.


HAVING 사용

SELECT Country,
       COUNT(*)
FROM Customers
GROUP BY Country
HAVING COUNT(*) >= 5;

국가별 고객 수를 계산한 후

조건에 맞는 국가만 선택합니다.


17-4. ORDER BY도 함께 사용할 수 있습니다.

SELECT Country,
       COUNT(*) AS CustomerCount
FROM Customers
GROUP BY Country
HAVING COUNT(*) >= 5
ORDER BY CustomerCount DESC;

고객이 많은 국가부터 출력됩니다.

실무에서는 HAVINGORDER BY를 함께 사용하는 경우가 매우 많습니다.


💡 잠깐! 이것도 알아두세요

HAVING은 반드시 GROUP BY와 함께 사용하는 경우가 대부분입니다.

또한 다음과 같은 집계 함수와 자주 사용됩니다.

  • COUNT()
  • SUM()
  • AVG()
  • MIN()
  • MAX()

자주 하는 실수

① 집계 함수를 WHERE에서 사용한다.

잘못된 예

SELECT Country,
       COUNT(*)
FROM Customers
WHERE COUNT(*) >= 5
GROUP BY Country;

왜 잘못일까요?

WHERE가 실행될 때는

아직 그룹이 만들어지지 않았기 때문입니다.


② HAVING만 사용하고 GROUP BY를 생략한다.

HAVING은

그룹을 대상으로 조건을 검사하는 명령어입니다.

따라서 대부분

GROUP BY와 함께 사용합니다.


③ WHERE와 HAVING를 같은 기능이라고 생각한다.

WHERE

행을 선택

HAVING

그룹을 선택

대상이 서로 다릅니다.


④ GROUP BY 없이 HAVING을 남용한다.

MySQL에서는 일부 경우 동작하기도 하지만,

초보자는

GROUP BY → HAVING

순서로 사용하는 습관을 들이는 것이 좋습니다.


실무에서는 어떻게 사용할까요?

회사에서는

HAVING을 이용하여

  • 주문이 많은 고객
  • 평균 가격이 높은 카테고리
  • 매출이 일정 금액 이상인 지역
  • 주문 건수가 많은 직원

등을 쉽게 찾을 수 있습니다.

경영 보고서와 통계 분석에서 매우 자주 사용됩니다.


실습

실습 1

고객이 5명 이상인 국가를 조회하세요.

SELECT Country,
       COUNT(*)
FROM Customers
GROUP BY Country
HAVING COUNT(*) >= 5;

실습 2

상품이 10개 이상인 카테고리를 조회하세요.

SELECT CategoryID,
       COUNT(*)
FROM Products
GROUP BY CategoryID
HAVING COUNT(*) >= 10;

실습 3

주문 건수가 많은 직원부터 출력하세요.

SELECT EmployeeID,
       COUNT(*) AS OrderCount
FROM Orders
GROUP BY EmployeeID
HAVING COUNT(*) >= 10
ORDER BY OrderCount DESC;

실무 미션

당신은 영업관리팀 직원입니다.

팀장님이

"고객이 많은 국가만 보고 싶습니다."

라고 요청했습니다.

다음 항목을 출력하세요.

  • Country
  • 고객 수
  • 고객 수가 5명 이상인 국가만
  • 고객 수가 많은 순으로 정렬

힌트)

GROUP BY, HAVING, ORDER BY를 모두 함께 사용합니다.


핵심 정리

✔ HAVING은 그룹을 만든 후 조건을 적용한다.

✔ WHERE는 행(Row)을 선택하고, HAVING은 그룹(Group)을 선택한다.

✔ HAVING은 GROUP BY와 함께 사용하는 경우가 대부분이다.

✔ HAVING에서는 COUNT(), SUM(), AVG(), MIN(), MAX() 같은 집계 함수를 사용할 수 있다.

🧠 SQL 실행 순서 기억하기

 

FROM
  ↓
WHERE
  ↓
GROUP BY
  ↓
HAVING
  ↓
SELECT
  ↓
ORDER BY

연습 문제

기본 문제

  1. HAVING은 언제 사용하는 명령어인가요?
  2. WHERE와 HAVING의 차이를 설명해 보세요.
  3. HAVING에서 자주 사용하는 함수는 무엇인가요?

응용 문제

  1. Products 테이블에서 상품이 8개 이상인 CategoryID를 조회하는 SQL을 작성하세요.
  2. Orders 테이블에서 주문 건수가 15건 이상인 직원(EmployeeID)을 조회하는 SQL을 작성하세요.
  3. Customers 테이블에서 국가별 고객 수를 계산한 후 고객 수가 많은 순으로 출력하는 SQL을 작성하세요.

도전 문제

Orders 테이블에서

직원별로

  • 주문 건수
  • 가장 빠른 주문일
  • 가장 늦은 주문일

을 출력하되,

주문 건수가 15건 이상인 직원만

조회하는 SQL을 작성해 보세요.


다음 장 예고

이번 장에서는 GROUP BY로 만든 그룹 중에서 원하는 그룹만 선택하는 HAVING을 배웠습니다.

하지만 통계를 만들다 보면 단순히 몇 개(Count)를 세는 것만으로는 부족합니다.

예를 들어

"국가별 총 주문 금액은 얼마인가요?"

"직원별 총 판매 수량을 계산해 주세요."

처럼 값을 모두 더해야 하는 경우가 많습니다.

이럴 때 사용하는 집계 함수가 바로 SUM()입니다.

다음 장에서는 여러 행의 값을 하나로 합산하는 SUM() 함수를 배우며, 그룹별 합계를 계산하는 방법까지 함께 익혀 보겠습니다.