✏️ SQLD

[SQLD] WHERE절과 HAVING절의 차이

haeriyouu 2025. 3. 1. 18:44

🔎 WHERE과 HAVING은 둘 다 조건을 필터링하는 역할을 한다.

  ➡️ 그러나 실행 순서와 대상이 다르다!

 

🔎 SQL 실행 순서 (쿼리 실행 플로우)

1️⃣ FROM: 테이블 지정

2️⃣ WHERE: 행(row) 단위로 필터링

3️⃣ GROUP BY: 그룹화 수행

4️⃣ HAVING: 그룹화된 데이터 필터링

5️⃣ SELECT: 최종 컬럼 선택

6️⃣ ORDER BY: 정렬 수행

 

💡 WHERE vs HAVING

구분 WHERE HAVING
실행 순서 GROUP BY 이전 GROUP BY 이후
작동 방식 개별 행(row) 필터링 그룹화된 데이터 필터링
사용 가능 데이터 원본 데이터만 사용 가능
= ❌집계 함수 사용 불가 ❌
집계 함수(AVG(), SUM(), COUNT()) 사용 가능
필터링 대상 개별 레코드 그룹별 결과

 

📌 HAVING을 이용한 그룹 필터링

SELECT GROUP_NAME,
	ROUND(AVG(HEIGHT),2),
	MAX(HEIGHT),
	MIN(HEIGHT)
FROM artist
HAVING GROUP_NAME IN ('aespa','IVE')
GROUP BY GROUP_NAME;

🔎 실행 과정

1️⃣ FROM artist ➡️ 테이블 조회

2️⃣ GROUP BY GROUP_NAME ➡️ GROUP_NAME별로 그룹화 수행

3️⃣ HAVING GROUP_NAME IN ('aespa', 'IVE') ➡️ 그룹화된 데이터 중 aespa와 IVE만 선택

4️⃣ SELECT ➡️ 결과 출력

✅ HAVING은 그룹화된 데이터에 조건을 적용하는 것이므로, GROUP BY 이후에 실행됨.

 

📌 WHERE를 이용한 행 필터링

SELECT GROUP_NAME,
	ROUND(AVG(HEIGHT),2),
	MAX(HEIGHT),
	MIN(HEIGHT)
FROM artist
WHERE GROUP_NAME IN ('aespa','IVE')
GROUP BY GROUP_NAME;

🔎 실행 과정

1️⃣ FROM artist ➡️ 테이블 조회

2️⃣ WHERE GROUP_NAME IN ('aespa', 'IVE') ➡️ 행 단위에서 aespa와 IVE만 남김

3️⃣ GROUP BY GROUP_NAME ➡️ 남은 데이터만 그룹화

4️⃣ SELECT ➡️ 결과 출력

✅ WHERE은 그룹화 전에 행을 필터링하기 때문에, 먼저 데이터를 줄인 후 GROUP BY 실행.

📌 결과 차이

- HAVING 사용 시: 모든 데이터를 그룹화한 후 조건을 적용 ➡️ 불필요한 그룹까지 먼저 생성

- WHERE 사용 시: 필요한 데이터만 남긴 후 그룹과 ➡️ 더 효율적!


❌ WHERE없이 HAVING만 사용한 경우

SELECT GROUP_NAME, HEIGHT
FROM artist
HAVING GROUP_NAME IN ('aespa','IVE');

🚨 HAVING은 집계 함수가 있는 경우에만 일반적으로 사용되며, 여기서는 GROUP BY가 없음.

🚨 WHERE대신 HAVING을 사용하면 그룹화된 결과가 아닌 개별 행을 필터링하려는 것처럼 보이므로 잘못된 사용.

 

❌ WHERE절이 GROUP BY보다 나중에 실행된 경우

SELECT GROUP_NAME, HEIGHT
FROM artist
GROUP BY GROUP_NAME 
WHERE AVG(HEIGHT) > 165;

🚨 WHERE은 GROUP BY 이전에 실행되므로 집계 함수(AVG)가 올 수 없음.

🚨 집계 함수(AVG, SUM, COUNT 등)는 GROUP BY 이후의 결과에 대해 적용되므로,  HAVING을 사용해야 함.

 

👉🏻 즉, WHERE은 원본 데이터를 먼저 필터링하고, HAVING은 그룹화된 데이터에서 특정 조건을 적용하는 것!