✔️ 난이도 4
레코드에 순위를 매기고자 할 때 대표적으로 생각나는 세가지 함수이다.
RANK
, DENSE_RANK
, ROW_NUMBER
는 전부 다음과 같은 포맷을 가지며,
특정 기준에 따라 순위를 매길 수 있는 윈도우 함수이다.
RANK() OVER (PARTITION BY column1 ORDER BY column2)
DENSE_RANK() OVER (PARTITION BY column1 ORDER BY column2)
ROW_NUMBER() OVER (PARTITION BY column1 ORDER BY column2)
윈도우 함수는 특성상 WHERE
절이나 HAVING
절에서 쓰일 수 없으므로
이 결과를 이용해서 필터링을 수행해야 하는 경우
1️⃣ 서브쿼리를 이용하거나
2️⃣ CTE(WITH
이용)를 이용하여
필터링을 수행할 수 있다.
이들의 각각의 세부사항과 차이점에 대하여 알아보자.
NTILE(n) OVER (PARTITION BY column1 ORDER BY column2)
요일 별 결제 금액으로 Top 3 를 지불한 영수증을 출력해주세요. 결제 금액은 total_bill 컬럼에 있습니다.
➡️ 계산 내용
day
별로 total_bill
를 정렬하여 그 순위가 3위인 것까지만 각각 추출한다.
예를 들어 금요일 손님들의 결제 금액이 각각 $10, $9, $9, $8, $5, $2 였다면 상위 결제 금액 3개는 $10, $9, $8입니다. 따라서 결제 금액이 $10, $9, $9, $8인 총 4개의 영수증을 각각 출력해야 합니다.
➡️ 계산 세부 사항
동일한 값에 대해서 같은 순위를 부여해야한다.
따라서 이에 적합하게 사용할 수 있는 DENSE_RANK
를 이용하여 순위를 매긴 뒤,
다시 그 결과에서 필요한 컬럼들을 추출하고 WHERE
절을 통해 3 이상의 순위만 추출한다.
SELECT day, time, sex, total_bill
FROM (SELECT *, dense_rank() over(PARTITION BY day ORDER BY total_bill DESC) d_rank
FROM tips)
WHERE d_rank <= 3;