DB 데이터/실무 중심 쿼리 활용법

RANK, ROW_NUMBER를 활용한 순위 처리

backend.log 2025. 5. 10. 18:05
728x90
반응형

📘 2-5. RANK, ROW_NUMBER를 활용한 순위 처리

실무에서는 사용자 활동 순위, 인기 상품 TOP N, 최신 데이터 추출 등 순위 기반 데이터가 자주 필요합니다.
이럴 때 윈도우 함수(Window Function)RANK(), ROW_NUMBER(), DENSE_RANK() 등을 활용하면 효율적으로 처리할 수 있습니다.

📌 기본 개념: ROW_NUMBER / RANK / DENSE_RANK

  • ROW_NUMBER(): 동일 값이 있어도 고유한 순번을 부여 (1, 2, 3...)
  • RANK(): 동일 값은 같은 순위를 부여하고 건너뜀 (1, 1, 3...)
  • DENSE_RANK(): 동일 값은 같은 순위를 부여하고 건너뛰지 않음 (1, 1, 2...)

✅ 예제 1: 사용자별 총 구매액 순위

SELECT 
  user_id,
  SUM(amount) AS total_spent,
  RANK() OVER (ORDER BY SUM(amount) DESC) AS spending_rank
FROM purchases
GROUP BY user_id;

✅ 예제 2: 상품별 최신 리뷰 1건만 추출 (ROW_NUMBER)

SELECT *
FROM (
  SELECT 
    review_id,
    product_id,
    content,
    created_at,
    ROW_NUMBER() OVER (PARTITION BY product_id ORDER BY created_at DESC) AS rn
  FROM reviews
) AS ranked_reviews
WHERE rn = 1;

설명: 상품별로 최신 리뷰 1건만 추출합니다. PARTITION BY로 그룹을 나누고, ORDER BY로 정렬 순서를 지정합니다.

✅ 예제 3: 월별 매출 상위 3개 상품 추출

SELECT *
FROM (
  SELECT 
    DATE_FORMAT(sale_date, '%Y-%m') AS sale_month,
    product_id,
    SUM(amount) AS monthly_total,
    RANK() OVER (PARTITION BY DATE_FORMAT(sale_date, '%Y-%m') ORDER BY SUM(amount) DESC) AS rk
  FROM sales
  GROUP BY sale_month, product_id
) AS ranked_sales
WHERE rk <= 3;

💡 실무 팁

  • ROW_NUMBER()는 고유 순번이 필요할 때 유용 (예: 최신 1건, 랜덤 추출 등)
  • RANK()는 공동 순위 허용, DENSE_RANK()는 순위 건너뛰지 않음
  • TOP N 쿼리를 구현할 때는 PARTITION BY와 함께 사용하는 게 핵심

📚 시리즈 마무리 안내

이번 편을 마지막으로 2. 실무 중심 쿼리 활용법 시리즈가 마무리됩니다.
다음 시리즈에서는 3. MySQL 성능 최적화와 관련된 실전 주제를 다룰 예정입니다. 🚀

728x90
반응형