SQL은 SELECT부터 써도, 결과는 FROM부터 만들어집니다
엔진은 원본 행을 먼저 모으고, 그다음 필터링하고 묶은 뒤, 마지막에 출력 컬럼과 정렬 기준을 확정합니다. 그래서 어느 단계에서 값이 생기는지 알아야 WHERE, HAVING, ORDER BY의 차이가 분명해집니다.
작성
실행
왜 중요한가
FROM / JOIN
조회 대상과 조인 결과를 먼저 만듦
2
1
출발점입니다. 어떤 행 집합을 다룰지 먼저 정해져야 뒤 절이 의미를 가집니다.
WHERE
개별 행을 먼저 거르는 단계
3
2
아직 그룹도, 별칭도 없습니다. 행 단위 조건만 검사하므로 집계값이나 SELECT 별칭은 참조할 수 없습니다.
GROUP BY
남은 행을 그룹 단위로 재구성
4
3
여기서부터 기준이 에서 그룹으로 바뀝니다. 이후 집계 함수가 의미를 갖습니다.
HAVING
만들어진 그룹을 다시 거름
5
4
집계 결과를 검사하는 위치입니다. COUNT(*) >= 3 같은 조건이 여기에서 가능합니다.
SELECT / DISTINCT
출력 컬럼을 정하고, 필요하면 중복 제거
1
5-6
별칭이 여기서 생깁니다. 따라서 cnt 같은 이름은 이전 단계가 아니라 이후 단계에서만 쓸 수 있습니다.
ORDER BY
완성된 결과를 기준으로 정렬
6
7
이미 만들어진 컬럼을 다루므로 SELECT 별칭을 그대로 정렬 기준으로 사용할 수 있습니다.
LIMIT / OFFSET
정렬까지 끝난 결과를 마지막으로 잘라냄
7
8
맨 마지막 단계입니다. 무엇을 볼지가 아니라 몇 개만 남길지를 결정합니다.
바로 연결되는 규칙
실행 순서를 알면 왜 가능한지 바로 설명됩니다
WHERE cnt > 3 불가
cnt는 아직 없습니다. 별칭은 SELECT 단계에서 생기므로, 더 먼저 실행되는 WHERE에서는 참조할 수 없습니다.
HAVING COUNT(*) >= 3 가능
그룹이 만들어진 뒤 검사하기 때문입니다. 집계 함수는 GROUP BY 이후에 의미가 생기므로 HAVING이 담당합니다.
ORDER BY cnt DESC 가능
정렬 시점에는 결과 컬럼이 이미 확정되어 있습니다. 그래서 SELECT에서 만든 별칭을 그대로 사용할 수 있습니다.