한 번 더 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 쿼리 실행 순서를 보자:
- 먼저
FROM이 실행돼서 테이블에서 행을 뽑아와. - 그 다음
WHERE가 적용돼서 조건에 맞는 행만 남겨. - 그 다음
GROUP BY로 그룹화가 돼. 이제 그룹별로 데이터가 묶여. HAVING이 적용돼서 조건에 맞는 그룹만 남겨.- 마지막으로
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;
여기서 일어나는 일:
students테이블에서age > 18인 행만 뽑아와 (WHERE사용).- 남은 행을
department별로 그룹화해. - 각 그룹마다 학생 평균 나이를 계산해.
- 평균 나이가 20 이하인 그룹은
HAVING으로 제외해. - 결과를 출력해.
조합해서 쓰는 예시
예시 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 |
설명:
- 먼저
age <= 18인 행을 지워 (WHERE조건). - 데이터를 학과별로 그룹화해 (
GROUP BY department). - 각 그룹마다 학생 수를 계산해.
- 학생이 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 쿼리의 절반 이상에서 꼭 필요하다는 얘기지 :)
GO TO FULL VERSION