오라클 ROW_NUMBER, RANK, DENSE_RANK 함수 이해하기

2024. 12. 31. 14:24IT정보/초보자를 위한 IT 팁

반응형

데이터베이스를 다루다 보면 특정 조건에 따라 데이터를 순서대로 정렬하거나, 그룹별로 순위를 매기는 작업이 필요할 때가 있습니다. 이때 오라클의 윈도우 함수(Window Function)인 ROW_NUMBER, RANK, DENSE_RANK를 사용하면 효율적으로 처리할 수 있습니다.


1. ROW_NUMBER 함수란?

ROW_NUMBER 함수는 결과 집합의 각 행에 고유한 순번을 부여합니다. 중복된 값이 있어도 순번이 고유하게 증가합니다.

주요 특징

  • 행마다 유일한 번호를 부여합니다.
  • 페이징 처리와 같이 고유한 순번이 필요한 경우 유용합니다.

사용법

SELECT 
    column1,
    ROW_NUMBER() OVER (PARTITION BY column2 ORDER BY column3) AS row_num
FROM table_name;

설명

  • PARTITION BY: 데이터를 그룹화합니다. (선택 사항)
  • ORDER BY: 순번을 매길 기준을 정합니다.

예제

SELECT 
    department_id,
    employee_name,
    ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) AS row_num
FROM employees;

결과

department_id employee_name salary row_num
1 Alice 5000 1
1 Bob 4500 2
2 Charlie 6000 1
2 David 5500 2

주의할 점

  • ORDER BY 절이 없으면 순번의 부여 기준이 명확하지 않을 수 있습니다. 항상 정렬 기준을 명확히 지정하세요.
  • 동일한 값이 있어도 순번은 고유하므로 특정 순서를 보장하려면 ORDER BY를 잘 설정해야 합니다.

2. RANK 함수란?

RANK 함수는 순위를 매기되, 동일한 값에 대해서는 동일한 순위를 부여합니다. 동일 순위를 부여한 후 다음 순위는 건너뜁니다.

주요 특징

  • 동일한 값이 있을 때 동일한 순위를 부여합니다.
  • 다음 순위는 건너뛰는 방식으로 순위를 매깁니다.

사용법

SELECT 
    column1,
    RANK() OVER (PARTITION BY column2 ORDER BY column3) AS rank
FROM table_name;

예제

SELECT 
    department_id,
    employee_name,
    RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rank
FROM employees;

결과

department_id employee_name salary row_num
1 Alice 5000 1
1 Bob 4500 2
1 Chris 4500 2
2 Charlie 6000 1
2 David 5500 2
2 Emma 5500 2

주의할 점

  • 동일한 순위를 가진 데이터가 많으면 다음 순위가 건너뛰므로 특정 범위의 데이터를 다룰 때 주의가 필요합니다.
  • 순위 건너뜀을 의도하지 않았다면 DENSE_RANK를 사용하세요.

3. DENSE_RANK 함수란?

DENSE_RANK 함수는 동일한 값에 대해 동일한 순위를 부여하며, 다음 순위는 건너뛰지 않습니다.

주요 특징

  • 동일한 순위를 부여하지만, 순위 건너뛰기가 없습니다.
  • 그룹 내 데이터를 분석할 때 자주 사용됩니다.

사용법

SELECT 
    column1,
    DENSE_RANK() OVER (PARTITION BY column2 ORDER BY column3) AS dense_rank
FROM table_name;

예제 1

SELECT 
    department_id,
    employee_name,
    DENSE_RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS dense_rank
FROM employees;

결과

department_id employee_name salary row_num
1 Alice 5000 1
1 Bob 4500 2
1 Chris 4500 2
2 Charlie 6000 1
2 David 5500 2
2 Emma 5500 2

 

예제 2

SELECT 
    department_id,
    employee_name,
    department_id,
    DENSE_RANK() OVER (ORDER BY department_id) AS dense_rank
FROM employees;

결과

department_id employee_name salary row_num
1 Alice 5000 1
1 Bob 4500 1
1 Chris 4500 1
2 Charlie 6000 2
2 David 5500 2
2 Emma 5500 2

주의할 점

  • 동일한 순위 그룹이 많을 경우 RANK와의 차이를 명확히 이해하고 사용해야 합니다.
  • 순위 건너뛰기가 없으므로 순위의 의미를 명확히 정의해야 합니다.


4. ROW_NUMBER, RANK, DENSE_RANK 비교

함수 중복 값 처리 다음 순위 처리 용도

ROW_NUMBER 순번 고유 순번 증가 페이징 처리 등
RANK 동일한 순위 부여 건너뜀 대회 순위, 순위 분석
DENSE_RANK 동일한 순위 부여 건너뛰지 않음 중복 값을 고려한 데이터 분석

 


5. 실무에서의 활용

페이징 처리 (ROW_NUMBER)

SELECT * FROM (
    SELECT 
        ROW_NUMBER() OVER (ORDER BY employee_id) AS row_num,
        employee_id,
        employee_name
    FROM employees
) WHERE row_num BETWEEN 21 AND 40;

순위별 데이터 추출 (RANK)

SELECT * FROM (
    SELECT 
        employee_name,
        RANK() OVER (ORDER BY salary DESC) AS rank
    FROM employees
) WHERE rank = 1;

순위 분석 (DENSE_RANK)

SELECT 
    department_id,
    employee_name,
    salary,
    DENSE_RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS dense_rank
FROM employees;

 


6. 요약

함수 이름 고유 순번 부여 동일한 값 처리 다음 순위 처리 방식 설명
ROW_NUMBER() ✅ 고유 순번 무시 (모두 다른 순번) 순차적으로 증가 동일한 값이라도 무조건 다른 순번 부여
RANK() ❌ 동일한 순번 같은 순위 부여 순위 건너뜀 공동 순위 후, 다음 순위는 건너뜀 (ex: 1, 1, 3)
DENSE_RANK() ❌ 동일한 순번 같은 순위 부여 순위 건너뛰지 않음 공동 순위 후, 다음 순위는 바로 다음 숫자 (ex: 1, 1, 2) 

이 함수들은 데이터 분석 및 순위 계산에서 유용하며, 실무에서 다양한 시나리오에 적용할 수 있습니다. 

 

#오라클오라클 태그 삭제#랭크랭크 태그 삭제#rankrank 태그 삭제#ROW_NUMBERROW_NUMBER 태그 삭제#dense_rankdense_rank 태그 삭제#순번순번 태그 삭제#orcleorcle 

 

 

반응형