TOP-N 선택 기준

동점 정책을 먼저 정해야 순위 함수가 정해진다

`ROW_NUMBER`, `RANK`, `DENSE_RANK`는 모두 순위를 붙이지만 TOP-N 필터에 들어가면 결과 개수와 동점 처리 방식이 달라진다. 먼저 “정확히 N행”인지 “같은 순위 모두 포함”인지 결정해야 한다.

1. 먼저 물어볼 것

판단
정확히 3개 상품만 필요한가?

슬롯, 광고 구좌, 페이지 크기처럼 행 수가 계약이면 고정한다.

3위와 같은 매출 상품을 빼도 되는가?

순위의 공정성이 중요하면 같은 점수는 같이 보여준다.

보고서에 1등급, 2등급, 3등급처럼 표시하는가?

등급 번호 자체가 사용자에게 보이면 빈 번호가 없는 편이 낫다.

`ROW_NUMBER`에는 안정적인 보조 정렬 키가 필요하다. 동점에서 무엇을 먼저 놓을지 정하지 않으면 실행마다 선택이 흔들릴 수 있다.

2. 같은 데이터에 세 함수 적용

동점 예시
상품 매출 RN R DR
노트북 980 1 1 1
태블릿 940 2 2 2
모니터 900 3 3 3
키보드 900 4 3 3
마우스 860 5 5 4

RN은 행마다 하나씩 증가하고, R은 공동 3위 뒤를 5위로 건너뛰며, DR은 다음 등급을 4로 이어 붙인다.

3. 필터는 바깥에서

순서
WITH ranked AS (
  SELECT product, sales,
         ROW_NUMBER() OVER (
           ORDER BY sales DESC, product_id
         ) AS rn,
         RANK() OVER (
           ORDER BY sales DESC
         ) AS rnk
  FROM product_sales
)
SELECT *
FROM ranked
WHERE rn <= 3;

윈도우 함수 결과는 같은 SELECT의 `WHERE`에서 바로 쓸 수 없다. CTE나 서브쿼리로 한 번 감싼 뒤 TOP-N 조건을 건다.

ROW_NUMBER <= 3

3행
1 노트북 980 2 태블릿 940 3 모니터 900

정확히 3개만 남긴다. 키보드는 같은 매출이어도 보조 정렬에서 밀린다.

RANK <= 3

4행
1 노트북 980 2 태블릿 940 3 모니터 900 3 키보드 900

공동 3위를 모두 포함한다. “상위 3위까지”라는 업무 문장에 맞다.

DENSE_RANK

등급
1등급 노트북 2등급 태블릿 3등급 모니터·키보드 4등급 마우스

순위 번호를 화면에 보여줄 때 빈 번호 없이 등급을 이어간다.