SQL 쿼리는 작성된 순서와 실제 실행되는 순서가 다릅니다. 이 실행 순서를 이해하는 것이 복잡한 쿼리를 작성하고 결과를 예측하는 데 필수적입니다.
SQL 실행 순서 (★★★★★ 필암기)
- FROM: 데이터를 가져올 테이블 지정.
JOIN
처리- WHERE: 행(Row) 단위 조건 필터링
- GROUP BY: 행들을 그룹화
- HAVING: 그룹별 조건 필터링
- SELECT: 최종 결과로 출력할 컬럼 지정
- ORDER BY: 결과 정렬
- LIMIT/ROWNUM: 최종 결과 개수 제한
JOIN
이 이 단계에서 모두 처리되어 임시 테이블이 생성됩니다.JOIN
과 관련된 모든 동작은 이 단계에서 시작됩니다.FROM
절에서 만들어진 임시 테이블의 개별 행(Row)에 조건을 적용해 필터링합니다.SUM
, AVG
, COUNT
)는 사용할 수 없습니다. (그룹핑 전이므로)SELECT
절에 정의된 컬럼 별칭을 사용할 수 없습니다. (실행 순서상 SELECT
보다 앞서기 때문)WHERE
에 집계 함수가 있으면 무조건 오답!SELECT
절에 집계 함수와 함께 사용되어야 의미가 있습니다.GROUP BY
로 그룹화된 결과에 대해 조건을 적용해 필터링합니다.WHERE
와 달리 집계 함수를 사용할 수 있습니다.GROUP BY
절이 없을 경우 SELECT
절의 모든 행을 하나의 그룹으로 간주합니다.HAVING
입니다.FROM
, WHERE
, GROUP BY
, HAVING
다음에 실행됩니다.AS
를 사용해 컬럼에 별칭을 부여할 수 있습니다.SELECT
절에서 부여된 별칭을 사용할 수 있습니다. (실행 순서상 SELECT
보다 뒤에 있기 때문)LIMIT
(MySQL/PostgreSQL 등): ORDER BY
이후에 실행되어 정렬된 결과에서 상위 N개를 가져옵니다.ROWNUM
(Oracle): ORDER BY
이전에 임시로 번호가 매겨집니다. 따라서 정렬된 결과에 대한 상위 N개를 얻으려면 반드시 서브쿼리를 사용해야 합니다.ROWNUM
의 특수성(정렬 전 실행)을 묻는 문제가 자주 나옵니다.SELECT
절의 별칭은 ORDER BY
에서만 사용 가능합니다.ROWNUM
: ORDER BY
보다 먼저 실행되므로, TOP-N
쿼리는 반드시 서브쿼리를 활용해야 합니다.1. 다음 중 SQL 실행 순서가 올바른 것은?
① SELECT → FROM → WHERE → GROUP BY → HAVING → ORDER BY
② FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY
③ FROM → GROUP BY → WHERE → HAVING → SELECT → ORDER BY
④ SELECT → FROM → GROUP BY → HAVING → WHERE → ORDER BY
2. HAVING
절에만 쓸 수 있는 것은?
① 일반 컬럼 조건
② 집계 함수 조건
③ 서브쿼리 결과
④ 별칭
3. Oracle에서 상위 5명의 급여를 기준으로 정렬하여 조회하는 쿼리 중 올바른 것은?
① SELECT * FROM Employee WHERE ROWNUM <= 5 ORDER BY sal DESC;
② SELECT * FROM Employee ORDER BY sal DESC WHERE ROWNUM <= 5;
③ SELECT * FROM (SELECT * FROM Employee ORDER BY sal DESC) WHERE ROWNUM <= 5;
④ SELECT * FROM (SELECT * FROM Employee) WHERE ROWNUM <= 5;
4. 다음 중 LEFT JOIN 시 주의할 점으로 옳은 것은?
① WHERE
조건에 걸어도 결과는 LEFT JOIN
과 동일하다.
② JOIN
조건은 반드시 ON
에 작성해야 LEFT JOIN
의 특성이 보장된다.
③ LEFT JOIN
은 반드시 GROUP BY
와 함께 써야 한다.
④ LEFT JOIN
은 ORDER BY
보다 먼저 실행된다.
FROM
이 가장 먼저, ORDER BY
가 가장 나중에 실행된다는 것을 기억하면 쉽게 풀 수 있습니다.HAVING
은 그룹핑 후에 적용되는 조건이므로, SUM
, AVG
같은 집계 함수에 대한 조건을 걸 때 사용됩니다. WHERE
절에서는 사용할 수 없습니다.ROWNUM
은 ORDER BY
보다 먼저 실행됩니다. 따라서 쿼리 ①과 ②처럼 작성하면, 정렬되지 않은 상태의 상위 5개를 가져오게 되어 원하는 결과가 나오지 않습니다. 서브쿼리를 사용해 먼저 정렬한 후 ROWNUM
조건을 걸어야 합니다.LEFT JOIN
의 WHERE
절에 조건을 걸면 결과가 INNER JOIN
과 동일해질 수 있습니다. LEFT JOIN
의 특성을 온전히 활용하려면 조인 조건은 반드시 ON
절에 작성해야 합니다.