SQL을 사용하다 보면 SELECT
에서 만든 별칭(alias)을 HAVING
이나 ORDER BY
절에서 그대로 쓰고 싶을 때가 많습니다.
그런데 어떤 경우는 잘 되고, 어떤 경우는 오류가 발생하죠.
이 포스팅에서는 왜 이런 차이가 생기는지, DBMS별 동작 차이, 실제 예제를 통해 깔끔하게 정리합니다.
SQL은 작성한 순서대로 실행되지 않습니다.
내부적으로는 아래 순서로 처리됩니다.
1. FROM
2. WHERE
3. GROUP BY
4. HAVING
5. SELECT
6. ORDER BY
7. LIMIT
👉 포인트
HAVING
은 SELECT
보다 먼저 실행되므로, SELECT
에서 정의한 alias를 참조할 수 없음ORDER BY
는 SELECT
이후 실행되므로, alias를 사용할 수 있음SELECT country, COUNT(DISTINCT certification) AS certification_count
FROM films
GROUP BY country
HAVING certification_count > 10; -- 에러 발생
왜 에러가 날까?
HAVING
은 SELECT
이전에 실행되므로, 아직 certification_count
라는 alias가 정의되지 않았기 때문입니다.SELECT country, COUNT(DISTINCT certification) AS certification_count
FROM films
GROUP BY country
HAVING COUNT(DISTINCT certification) > 10;
PostgreSQL/Oracle처럼 엄격한 DBMS에서는 서브쿼리를 사용하면 alias를 재활용할 수 있습니다.
SELECT country, certification_count
FROM (
SELECT country, COUNT(DISTINCT certification) AS certification_count
FROM films
GROUP BY country
) AS sub
WHERE certification_count > 10;
ORDER BY
는 SELECT
이후 실행되므로, alias가 이미 존재합니다.
따라서 다음과 같이 alias를 직접 사용할 수 있습니다.
SELECT country, AVG(budget) AS average_budget
FROM films
GROUP BY country
HAVING AVG(budget) > 1000000000
ORDER BY average_budget DESC; -- ✅ alias 사용 가능
DBMS | HAVING에서 alias 사용 | ORDER BY에서 alias 사용 |
---|---|---|
MySQL | ✅ 가능 (비표준 허용) | ✅ 가능 |
SQL Server | ✅ 가능 (비표준 허용) | ✅ 가능 |
PostgreSQL | ❌ 불가 | ✅ 가능 |
Oracle | ❌ 불가 | ✅ 가능 |
MySQL은 ANSI SQL 표준을 엄격히 따르지 않고, HAVING
에서도 alias를 사용할 수 있도록 허용합니다.
하지만 이 방식은 다른 DBMS와 호환되지 않을 수 있으므로 주의해야 합니다.
HAVING 절
ORDER BY 절
SELECT
이후 실행 → alias 사용 가능MySQL/SQL Server에서는 비표준 기능으로 HAVING에서도 alias 사용 가능
💡 "HAVING은 SELECT보다 먼저, ORDER BY는 SELECT 이후"
이 차이 하나만 기억해도, alias 사용 가능 여부를 바로 이해할 수 있습니다.