C

SQL WHERE와 HAVING 차이: 언제 무엇을 쓸까

2026-05-29 · Database · SQL · WHERE · HAVING

SQL WHERE와 HAVING 차이의 핵심

SQL WHERE와 HAVING 차이를 한 문장으로 요약하면 이렇습니다. WHERE는 그룹으로 묶기 전 개별 행을 거르고, HAVING은 GROUP BY로 묶은 뒤 집계 결과를 거릅니다. 둘 다 "조건으로 필터링한다"는 점은 같지만, 적용되는 시점과 대상이 다릅니다. 이 차이를 모르면 WHERE COUNT(*) > 5 같은 잘못된 쿼리를 작성하게 됩니다.

예제로 주문 테이블(orders)을 사용합니다.

-- orders
id | customer | amount | status
1  | 김철수    | 5000   | paid
2  | 김철수    | 3000   | paid
3  | 이영희    | 7000   | cancelled
4  | 이영희    | 2000   | paid
5  | 박민수    | 1000   | paid

WHERE: 그룹화 전 행 필터링

WHERE는 GROUP BY가 동작하기 전에 개별 행을 걸러냅니다. 예를 들어 취소된 주문(cancelled)을 빼고 싶다면 WHERE를 씁니다.

SELECT customer, SUM(amount) AS total
FROM orders
WHERE status = 'paid'   -- 행 단위 필터 (그룹화 전)
GROUP BY customer;

-- 결과
김철수 | 8000
이영희 | 2000   -- 7000짜리 cancelled는 제외됨
박민수 | 1000

중요한 점은 WHERE 절에서는 SUM, COUNT 같은 집계 함수를 쓸 수 없다는 것입니다. 그 시점에는 아직 그룹이 만들어지지 않았기 때문입니다.

HAVING: 그룹화 후 집계 결과 필터링

HAVING은 GROUP BY로 그룹을 만든 뒤, 그 그룹의 집계값을 기준으로 필터링합니다. 예를 들어 "결제 합계가 5000 이상인 고객만" 보고 싶다면 HAVING을 씁니다.

SELECT customer, SUM(amount) AS total
FROM orders
WHERE status = 'paid'
GROUP BY customer
HAVING SUM(amount) >= 5000;   -- 집계 결과 필터 (그룹화 후)

-- 결과
김철수 | 8000

이렇게 WHERE와 HAVING은 함께 쓰는 경우가 많습니다. WHERE로 먼저 불필요한 행을 줄이고, GROUP BY로 묶은 뒤, HAVING으로 그룹 단위 조건을 거는 흐름입니다.

실행 순서로 이해하기

SQL은 작성 순서와 실제 실행 순서가 다릅니다. 논리적 실행 순서를 알면 WHERE와 HAVING의 차이가 자연스럽게 이해됩니다.

1. FROM      -- 테이블 선택
2. WHERE     -- 행 필터링 (집계 함수 불가)
3. GROUP BY  -- 그룹으로 묶기
4. HAVING    -- 그룹 필터링 (집계 함수 가능)
5. SELECT    -- 컬럼/별칭 계산
6. ORDER BY  -- 정렬

WHERE가 GROUP BY보다 먼저(2단계), HAVING이 GROUP BY보다 나중(4단계)이라는 점이 핵심입니다.

WHERE vs HAVING 비교표

구분WHEREHAVING
적용 시점그룹화 전그룹화 후
필터 대상개별 행그룹(집계 결과)
집계 함수사용 불가사용 가능
GROUP BY 필요불필요대부분 필요

실전 팁

성능을 위해 가능한 조건은 WHERE에 먼저 거세요. WHERE로 행을 미리 줄이면 그룹화 대상이 적어져 더 빠릅니다. HAVING에는 "집계값에 대한 조건"만 남기는 것이 원칙입니다. 예를 들어 HAVING status = 'paid'처럼 집계와 무관한 조건을 HAVING에 두는 것은 비효율적이며, 이런 조건은 WHERE로 옮겨야 합니다.

흔한 실수

1. WHERE에 집계 함수 쓰기. WHERE SUM(amount) > 5000은 오류입니다. 집계 조건은 HAVING으로 가야 합니다.

2. HAVING에서 SELECT 별칭 의존. 일부 DB(예: 표준에 엄격한 환경)에서는 HAVING total >= 5000처럼 SELECT의 별칭을 HAVING에서 못 쓸 수 있습니다. 실행 순서상 SELECT가 HAVING보다 늦기 때문입니다. 안전하게 HAVING SUM(amount) >= 5000처럼 원래 식을 쓰는 것을 권장합니다(MySQL은 별칭을 허용합니다).

자주 묻는 질문

Q1. GROUP BY 없이 HAVING만 쓸 수 있나요?

가능합니다. GROUP BY가 없으면 전체 행이 하나의 그룹으로 취급되어, SELECT COUNT(*) FROM orders HAVING COUNT(*) > 3처럼 전체 집계에 조건을 걸 수 있습니다. 다만 흔한 패턴은 아닙니다.

Q2. WHERE와 HAVING을 동시에 쓰면 순서는?

WHERE가 먼저 행을 거른 뒤 GROUP BY로 묶고, 그다음 HAVING이 그룹을 거릅니다. 작성할 때는 WHERE → GROUP BY → HAVING 순서로 씁니다.

Q3. 같은 조건을 WHERE에 둘지 HAVING에 둘지 헷갈려요.

조건이 집계 함수(SUM, COUNT 등)를 포함하면 HAVING, 개별 행의 값(컬럼 비교)만 본다면 WHERE입니다. 성능상 집계와 무관한 조건은 항상 WHERE에 두세요.

SQL WHERE와 HAVING 차이: 언제 무엇을 쓸까 | CodeMaster 블로그 | CodeMaster