상세 컨텐츠

본문 제목

RANK() OVER (ORDER BY.... ) 순위 랭크함수 사용 방법은?

IT/DB

by JR 2026. 6. 2. 14:23

본문

300x250

 

 

 

RANK()는 순위(랭킹)를 매겨주는 윈도우 함수입니다.

SQL에서 "TOP N", "상위/하위 순위" 같은 분석을 할 때 가장 자주 쓰여요. 

 

기본 문법

RANK() OVER (
    [PARTITION BY 그룹기준컬럼]   -- 선택: 그룹별로 순위 매기기
    ORDER BY 정렬기준컬럼 [ASC|DESC]  -- 필수: 무엇을 기준으로 순위를 매길지
)

가장 단순한 예시: 거래건수 상위 회원 순위

SELECT
    user_id                                          AS 유저ID
  , COUNT(*)                                         AS 총_거래건수
  , RANK() OVER (ORDER BY COUNT(*) DESC)             AS 순위
FROM
    transactions
WHERE
    transaction_dt >= DATE'2025-01-01'
    AND transaction_dt <  DATE'2025-05-01'
GROUP BY
    user_id
ORDER BY
    순위
;

 

결과 예시:

유저ID 총_거래건수 순위
A 120 1
B 95 2
C 95 2 ← 동률
D 80 4 ← 3위 건너뜀
E 75 5

 

RANK() vs DENSE_RANK() vs ROW_NUMBER() 비교

 

세 함수 모두 순위를 매기지만 동률 처리 방식이 달라요.

점수 RANK() DENSE_RANK() ROW_NUMBER()
100 1 1 1
95 2 2 2
95 2 2 3
90 4 3 4
85 5 4 5
  • RANK(): 동률 시 같은 순위, 다음 순위 건너뜀 (1,2,2,4) → 올림픽 메달 방식
  • DENSE_RANK(): 동률 시 같은 순위, 다음 순위 안 건너뜀 (1,2,2,3) → 등급 방식
  • ROW_NUMBER(): 동률 무시하고 무조건 일련번호 (1,2,3,4) → 페이징/유니크 번호용

PARTITION BY로 그룹별 순위 매기기

전체가 아니라 카테고리별 순위를 매기고 싶을 때 사용합니다. 예: 제휴사별로 거래액 상위 회원 순위.

SELECT
    partner_id                                       AS 제휴사ID
  , user_id                                          AS 유저ID
  , SUM(amount)                                      AS 총_거래금액
  , RANK() OVER (
        PARTITION BY partner_id
        ORDER BY SUM(amount) DESC
    )                                                AS 제휴사내_순위
FROM
    transactions
WHERE
    transaction_dt >= DATE'2025-01-01'
    AND transaction_dt <  DATE'2025-05-01'
GROUP BY
    partner_id, user_id
ORDER BY
    제휴사ID, 제휴사내_순위
;

 

결과 예시:

제휴사ID 유저ID 총_거래금액 제휴사내_순위
P001 A 50000 1
P001 B 30000 2
P001 C 20000 3
P002 D 80000 1 ← 다시 1부터
P002 E 45000 2

 

실전 활용: TOP 3만 추출하기

 

RANK()는 SELECT 절에서 바로 WHERE로 못 거릅니다 (윈도우 함수는 WHERE보다 나중에 계산되기 때문).

그래서 서브쿼리/CTE로 감싼 뒤 WHERE에 조건을 거는 패턴을 자주 씁니다.

SELECT
    제휴사ID
  , 유저ID
  , 총_거래금액
  , 제휴사내_순위
FROM (
    SELECT
        partner_id                                   AS 제휴사ID
      , user_id                                      AS 유저ID
      , SUM(amount)                                  AS 총_거래금액
      , RANK() OVER (
            PARTITION BY partner_id
            ORDER BY SUM(amount) DESC
        )                                            AS 제휴사내_순위
    FROM
        transactions
    WHERE
        transaction_dt >= DATE'2025-01-01'
        AND transaction_dt <  DATE'2025-05-01'
    GROUP BY
        partner_id, user_id
) t
WHERE
    제휴사내_순위 <= 3                              -- 제휴사별 TOP 3만
ORDER BY
    제휴사ID, 제휴사내_순위
;

정리

  • RANK(): 순위 매기는 윈도우 함수, 동률은 같은 순위로 처리하고 그다음 순위는 건너뜀
  • ORDER BY (필수): 어떤 값 기준으로 순위를 매길지 → DESC는 큰 값이 1위, ASC는 작은 값이 1위
  • PARTITION BY (선택): 전체가 아닌 그룹 단위로 순위를 매길 때 사용
  • TOP N 추출: 서브쿼리로 감싼 뒤 외부 WHERE에서 순위 <= N으로 필터링

CUBRID도 표준 SQL 윈도우 함수를 지원하니 위 문법 그대로 사용 가능합니다. 

 

 

 

300x250

관련글 더보기