WHERE과 HAVING의 차이를 비교하기 전에 우선 SQL쿼리의 실행 순서를 알아야합니다.
SELECT ename
FROM emp
WHERE empno=10
GROUP BY ename
HAVING count(*)>=1
ORDER BY ename;
위 쿼리에서 SELECT문의 실행 순서는 FROM > WHERE > GROUP BY > HAVING > SELECT > ORDER BY입니다.
SELECT * FROM 테이블 WHERE 조건절;
• 역할: 데이터를 그룹화(GROUP BY) 이전에, 개별 행(row) 수준에서 조건을 필터링.
• 적용 대상: 테이블의 개별 행.
• 사용 위치: FROM 절 바로 다음에 실행.
• 집계 함수(예: SUM, AVG)는 사용할 수 없음.
WHERE은 기본적인 조건절로 항상 FROM 뒤에 위치하며 다양한 비교 연산자로 구체적인 조건을 줄 수 있습니다.
SELECT * FROM 테이블 GROUP BY 필드 HAVING 조건절;
• 역할: 데이터를 그룹화(GROUP BY) 이후에, 그룹 전체를 대상으로 조건을 필터링.
• 적용 대상: 그룹화된 데이터(aggregate data).
• 사용 위치: GROUP BY 절 뒤에 실행.
• 집계 함수(예: SUM, AVG)를 사용할 수 있음.
항상 GROUP BY 뒤에 위치하며 WHERE과 마찬가지로 다양한 비교 연산자로 조건을 줄 수 있습니다.
둘 다 필드에 조건을 줄 수 있다는 것은 동일하지만, WHERE은 기본적으로 모든 필드에 조건을 줄 수 있지만 HAVING은 GROUP BY로 그룹화 된 필드에 조건을 줄 수 있습니다. 또한, HAVING에서 조건을 줄 필드는 SELECT에 반드시 명시되어 있어야 합니다.
| 구분 | WHERE | HAVING |
|---|---|---|
| 적용 시점 | 그룹화(GROUP BY) 이전 | 그룹화(GROUP BY) 이후 |
| 적용 대상 | 테이블의 개별 행(row) | 그룹화된 집계 데이터 |
| 집계 함수 사용 가능 여부 | 불가능 | 가능 |
| 사용 위치 | GROUP BY 이전 | GROUP BY 이후 |
| 필터링 기준 | 개별 행을 기준으로 조건 검사 | 그룹화된 데이터를 기준으로 조건 검사 |
우선 직업별 급여 합계 중에 급여 합계가 1000이상인 직업을 조회하는 상황을 가정해봅시다.
SELECT job, SUM(salary) AS total_salary
FROM employees
WHERE SUM(salary) >= 1000 -- 오류 발생
GROUP BY job;
SUM(salary)는 그룹화 이후에 계산되므로, WHERE(그룹화 이전에 적용됨)에서 사용할 수 없습니다.
SELECT job, SUM(salary) AS total_salary
FROM employees
GROUP BY job
HAVING SUM(salary) >= 1000;
쿼리 실행 흐름:
• 1단계:FROM employees→ 직원 테이블 로드.
• 2단계:GROUP BY job→ 직업별로 데이터를 그룹화.
• 3단계:SUM(salary)→ 각 그룹의 급여 합계 계산.
• 4단계:HAVING SUM(salary) >= 1000→ 급여 합계가 1000 이상인 그룹만 필터링.
GROUP BY는 데이터를 그룹 단위로 묶는 작업을 합니다. 각 그룹에 대해 집계함수(SUM, AVG, COUNT, MAX, MIN 등)가 적용되며, 이 작업은 그룹화 후에 수행됩니다.
HAVING절은 GROUP BY 이후에 실행됩니다. 따라서, 이미 그룹화가 끝난 상태에서 SUM(salary) 값을 조건으로 사용할 수 있습니다.
HAVING은 그룹화된 결과에서 집계 결과를 필터링하므로 올바르게 작동합니다.
참고자료