CodeGym /행동 /SQL SELF /WHERE랑 HAVING 비교: 실행 순서랑 예시로 완전 파헤치기

WHERE랑 HAVING 비교: 실행 순서랑 예시로 완전 파헤치기

SQL SELF
레벨 8, 레슨 2
사용 가능

한 번 더 SQL에서 연산이 실행되는 순서랑, WHERE랑 HAVING이 뭘 할 수 있고 뭘 못 하는지 정리해보자. 이거 진짜 중요한 부분이라서, 이걸 잘 알아야 SQL 쿼리 짤 때 여러가지 디테일을 이해할 수 있어. 꼭 제대로 이해하고 넘어가자!

그럼 WHERE랑 HAVING이 뭐가 다른지, 언제 하나를 쓰고 언제 다른 걸 써야 하는지, 그리고 둘이 어떻게 연결되는지 궁금하지? 이걸 알면 쿼리 논리에서 헷갈릴 일 없고, 데이터 필터링도 훨씬 효율적으로 할 수 있어. WHERE랑 HAVING에 대해 우리가 아는 걸 정리해보자.

WHERE가 뭐야?

WHERE는 그룹화나 집계 함수 적용 전에 행을 필터링할 때 쓰는 조건이야. 즉, 테이블에서 조건에 맞는 행만 먼저 뽑고, 그 다음에 남은 데이터로 그룹화가 진행되는 거지.

👉 시장에서 과일 고르는 걸 생각해봐. WHERE는 네가 사과를 크기나 색깔로 분류하기 전에, 미리 상태 안 좋은 사과를 골라내는 필터야.

예시:

SELECT *
FROM students
WHERE age > 18;

이 쿼리는 18살 넘는 학생들만 다른 연산 전에 뽑아와.

HAVING이 뭐야?

HAVING는 그룹화(GROUP BY) 이후에 적용되는 필터야. 이건 그룹화된 데이터에 조건을 걸 수 있어서, 예를 들어 학생 평균 점수가 80점 넘는 그룹만 남길 수 있어.

👉 다시 사과 예시로 돌아가면, HAVING는 이미 사과를 바구니(그룹)별로 나눈 다음에, 예를 들어 10개 넘게 들어있는 바구니만 고르는 필터야.

예시:

SELECT 바구니, COUNT(*)
FROM 사과
GROUP BY 바구니
HAVING COUNT(*) > 10;

이 쿼리는 사과가 10개 넘는 바구니만 뽑아와.

주요 차이점:

특징 WHERE HAVING
적용 시점 그룹화 전에 행 필터링 그룹화 후에 그룹 필터링
집계 함수 사용 집계 함수 사용 불가 집계 함수 사용 가능
목적 그룹화 전에 불필요한 행 제거 조건에 안 맞는 그룹 제거

WHERE, GROUP BY, HAVING 실행 순서

WHERE랑 HAVING이 어떻게 동작하는지 더 잘 이해하려면, SQL 쿼리 실행 순서를 보자:

  1. 먼저 FROM이 실행돼서 테이블에서 행을 뽑아와.
  2. 그 다음 WHERE가 적용돼서 조건에 맞는 행만 남겨.
  3. 그 다음 GROUP BY로 그룹화가 돼. 이제 그룹별로 데이터가 묶여.
  4. HAVING이 적용돼서 조건에 맞는 그룹만 남겨.
  5. 마지막으로 SELECT 결과가 뽑혀.

도식으로 보면 이렇게 돼:

1. FROM → 2. WHERE → 3. GROUP BY → 4. HAVING → 5. SELECT

예시:

SELECT department, AVG(age) AS avg_age
FROM students
WHERE age > 18
GROUP BY department
HAVING AVG(age) > 20;

여기서 일어나는 일:

  1. students 테이블에서 age > 18인 행만 뽑아와 (WHERE 사용).
  2. 남은 행을 department별로 그룹화해.
  3. 각 그룹마다 학생 평균 나이를 계산해.
  4. 평균 나이가 20 이하인 그룹은 HAVING으로 제외해.
  5. 결과를 출력해.

조합해서 쓰는 예시

예시 1: 그룹화 전후로 필터링

조건: 18살 넘는 학생만 고려해서, 학생이 5명 넘는 학과 찾기.

원본 테이블 students

id name department age gpa
1 Alex Lin ComputerSci 20 3.8
2 Maria Chi Math 22 3.5
3 Anna Song ComputerSci 19 4.0
4 Otto Art Math 17 3.9
5 Liam Park Physics 21 3.7
6 Jane Doe ComputerSci 23 3.6
7 Tom Brown Math 25 3.4
8 Sara White Math 19 3.8
9 John Smith ComputerSci 20 3.7
10 Emily Green Physics 18 3.9
11 Mark Blue ComputerSci 21 3.5
12 Zoe Black Math 22 3.6
13 Max Gray ComputerSci 20 3.9
14 Eva Gold Math 23 3.7
15 Nick Silver Physics 19 3.8

쿼리:

SELECT department, COUNT(*) AS student_count
FROM students
WHERE age > 18
GROUP BY department
HAVING COUNT(*) > 5;

결과: -- 쿼리 결과

department student_count
ComputerSci 6

설명:

  1. 먼저 age <= 18인 행을 지워 (WHERE 조건).
  2. 데이터를 학과별로 그룹화해 (GROUP BY department).
  3. 각 그룹마다 학생 수를 계산해.
  4. 학생이 5명 이하인 그룹은 제외해 (HAVING COUNT(*) > 5).

예시 2: WHERE 대신 HAVING을 써야 하는데 실수한 경우

조건: 평균 나이가 22살 넘는 학과 찾기.

잘못된 쿼리:

SELECT department, AVG(age) AS avg_age
FROM students
WHERE AVG(age) > 22
GROUP BY department;

오류: SQL에서는 WHERE에서 AVG 같은 집계 함수를 쓸 수 없어. 이 시점엔 집계가 아직 안 됐거든.

정답 쿼리:

SELECT department, AVG(age) AS avg_age
FROM students
GROUP BY department
HAVING AVG(age) > 22;

여기서는 AVG(age) > 22 조건이 그룹화 이후에 적용돼.

실전 꿀팁

행을 필터링하고 싶으면 WHERE를 써. 예시: 5000 넘는 월급 받는 직원 찾기.

SELECT *
FROM employees
WHERE salary > 5000;

그룹을 필터링하고 싶으면 HAVING을 써. 예시: 전체 월급이 10만 넘는 부서 찾기.

SELECT department, SUM(salary) AS total_salary
FROM employees
GROUP BY department
HAVING SUM(salary) > 100000;

복잡한 조건엔 WHERE랑 HAVING을 같이 써도 돼.

예시: 인구가 100만 넘는 도시만 고려해서, 전체 인구가 1천만 넘는 나라 찾기.

SELECT country, SUM(population) AS total_population
FROM cities
WHERE population > 1000000
GROUP BY country
HAVING SUM(population) > 10000000;

자주 하는 실수랑 해결법

가장 흔한 실수 중 하나가 WHERE랑 HAVING을 헷갈리는 거야. 예를 들어, WHERE에서 집계 함수를 쓰려고 하면:

SELECT department, COUNT(*)
FROM students
WHERE COUNT(*) > 10
GROUP BY department;

이런 쿼리는 에러가 나. 왜냐면 WHERE 단계에선 집계 연산이 아직 안 됐으니까. 정답은 HAVING을 써야 해:

SELECT department, COUNT(*)
FROM students
GROUP BY department
HAVING COUNT(*) > 10;

또 다른 실수는 WHERE에 잘못된 조건을 쓰는 거야. 예를 들어:

SELECT department, AVG(age) AS avg_age
FROM students
WHERE avg_age > 20
GROUP BY department;

여기서 avg_age > 20 조건은 잘못됐어. avg_age는 아직 계산이 안 됐거든. 해결법은 이 조건을 HAVING으로 옮기는 거야:

SELECT department, AVG(age) AS avg_age
FROM students
GROUP BY department
HAVING AVG(age) > 20;

이제 WHERE랑 HAVING이 뭐가 다른지, 어떻게 써야 하는지, 그리고 흔한 실수를 어떻게 피하는지 확실히 알았지? 이거 알면 복잡한 리포트 만들 때, 데이터 분석할 때, 쿼리 최적화할 때 다 써먹을 수 있어. 즉, 네가 앞으로 쓸 SQL 쿼리의 절반 이상에서 꼭 필요하다는 얘기지 :)

2
과제
SQL SELF, 레벨 8, 레슨 2
잠금
나이가 18세를 초과하는 학생이 5명보다 많은 학과 찾기
나이가 18세를 초과하는 학생이 5명보다 많은 학과 찾기
2
과제
SQL SELF, 레벨 8, 레슨 2
잠금
23세를 초과하는 학생의 최대 나이가 있는 학과 찾기
23세를 초과하는 학생의 최대 나이가 있는 학과 찾기
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION