본문 바로가기
카테고리 없음

[oracle] RANK / DENSE_RANK / ROW_NUMBER - 이해하기 쉽게

by 플랜비BB 2024. 8. 8.
윈도우 함수로, 데이터 순위로 나타내는 데 사용된다.
  • RANK - 동일한 값이 있을 경우 같은 순위를 부여하고, 그 다음 순위는 건너뛰고 다음으로 작은 순위를 부여한다.
  • DENSE_RANK - 동일한 값이 있을 경우에도 같은 순위를 부여하지만, 그 다음 순위는 건너뛰지 않는다.
  • ROW_NUMBER - 각 행에 순차적으로 숫자를 할당한다.

 

예제쿼리.txt
0.00MB

 

1. 예제 테이블

STUDENT_ID      SCORE
---------- ----------
         1         85
         2         92
         3         78
         4         85
         5         92
         6         78
         7         85

 

2. RANK

SELECT 
    student_id,
    score,
    RANK() OVER (ORDER BY score DESC) AS rank_score
FROM 
    scores;

STUDENT_ID      SCORE RANK_SCORE
---------- ---------- ----------
         2         92          1
         5         92          1
         7         85          3 -- 2를 건너뛰고 3으로
         1         85          3
         4         85          3
         6         78          6
         3         78          6

 

3. DENSE_RANK

SELECT 
    student_id,
    score,
    DENSE_RANK() OVER (ORDER BY score DESC) AS rank_score
FROM 
    scores;

STUDENT_ID      SCORE RANK_SCORE
---------- ---------- ----------
         2         92          1
         5         92          1
         7         85          2 -- RANK와 다르게 다음 순번을 건너뛰지 않음
         1         85          2
         4         85          2
         6         78          3
         3         78          3
         
// 동일한 값이 없다면 RANK와 동일한 값을 가진다.

 

4. RANK와 DENSE_RANK 비교

SELECT 
    student_id,
    score,
    RANK() OVER (ORDER BY score DESC) AS RANK,
    DENSE_RANK() OVER (ORDER BY score DESC) AS DENSE
FROM 
    scores;
    
STUDENT_ID      SCORE       RANK      DENSE
---------- ---------- ---------- ----------
         2         92          1          1
         5         92          1          1
         7         85          3          2
         1         85          3          2
         4         85          3          2
         6         78          6          3
         3         78          6          3

 

5. ROW_NUMBER()

SELECT 
    student_id,
    score,
    ROW_NUMBER() OVER (ORDER BY score DESC) AS row_num
FROM 
    scores;

STUDENT_ID      SCORE    ROW_NUM
---------- ---------- ----------
         2         92          1
         5         92          2
         7         85          3
         1         85          4
         4         85          5
         6         78          6
         3         78          7
					 
// ORDER BY로 정렬한 결과값이 동일하다.
SELECT 
    student_id,
    score
FROM 
    scores
ORDER BY score DESC;

STUDENT_ID      SCORE
---------- ----------
         2         92
         5         92
         7         85
         1         85
         4         85
         6         78
         3         78
-- PARTITION BY 절
일반적으로 PARTITION BY 절을 사용하여 특정 컬럼 또는 표현식의 값이 동일한 행들을 그룹화하고,
그 안에서 ROW_NUMBER()를 계산한다.

SELECT 
    student_id,
    score,
    ROW_NUMBER() OVER (PARTITION BY score ORDER BY score) AS row_num
FROM 
    scores;

STUDENT_ID      SCORE    ROW_NUM
---------- ---------- ----------
         6         78          1
         3         78          2
         7         85          1
         1         85          2
         4         85          3
         2         92          1
         5         92          2

 

6. ROW_NUMBER VS ROWNUM

ROWNUM은 특정 조건을 만족하는 결과 집합에서 행의 순서를 나타내는 가상의 컬럼이다.
일반적으로 ROWNUM은 서브쿼리나 특정 조건을 만족하는 행의 개수를 제한하는 데 사용된다.

SELECT *
FROM scores
WHERE ROWNUM <= 3;

STUDENT_ID      SCORE
---------- ----------
         1         85
         2         92
         3         78

// 상위 3개의 행을 선택한다.
// ROW_NUMBER과 이름은 비슷하지만 두 개념은 다른 목적과 사용 방식을 가지고 있으며,
// 상황에 맞게 적절히 선택하여 사용해야 한다.