실행 순서
rn은 WHERE가 지난 뒤에 생긴다
윈도우 함수 결과는 WHERE 단계에서 아직 존재하지 않습니다. 먼저 내부 SELECT에서 순위 열을 만들고, 바깥 쿼리에서 그 열을 필터링해야 합니다.
불가
같은 SELECT의 WHERE에서 rn 별칭을 바로 참조하지 않는다.
계산
ROW_NUMBER는 WHERE 이후 SELECT 단계에서 붙는다.
해결
서브쿼리나 CTE 밖에서 rn <= 3을 적용한다.
막히는 지점
같은 SELECT의 WHERE는 SELECT에서 붙는 rn을 아직 모른다.
풀리는 지점
CTE나 서브쿼리 밖으로 나오면 rn이 보통 컬럼처럼 보인다.
입력 행을 먼저 줄인다. 이 시점에는 rn 열이 없다.
집계가 있으면 그룹 결과 행이 만들어진다.
ROW_NUMBER 같은 윈도우 결과가 각 행 옆에 붙는다.
이미 만들어진 rn을 바깥 쿼리에서 필터링한다.
한 SELECT 안에서 걸면 실패
rn 없음SELECT name, salary,
ROW_NUMBER() OVER (
ORDER BY salary DESC
) AS rn
FROM employees
WHERE rn <= 3;
WHERE
rn을 찾지만 아직 만들어지지 않았다.
SELECT
그 다음에야 ROW_NUMBER 결과가 rn으로 붙는다.
한 겹 감싼 뒤 바깥에서 필터
rn 사용 가능WITH ranked AS (
SELECT name, salary,
ROW_NUMBER() OVER (
ORDER BY salary DESC
) AS rn
FROM employees
)
SELECT *
FROM ranked
WHERE rn <= 3;
내부 SELECT
원본 행에 rn 열을 먼저 만든다.
외부 WHERE
ranked 결과의 rn을 조건으로 안전하게 거른다.
부서, 날짜, 상태처럼 원본 행을 줄이는 조건은 윈도우 계산 전에 안쪽 WHERE에 둔다.
민준1
서연2
도윤3
BigQuery, Snowflake 등은 QUALIFY를 제공하지만 논리적으로는 윈도우 계산 이후 필터라는 점이 같다.