Database/MS SQL

[MS SQL Server] #10_순위 함수(RANK, DENSE_RANK, ROW_NUMBER, NTILE)

Tigercow.Door 2019. 5. 15. 18:30


안녕하세요. 문범우입니다.

이번 글에서는 SQL Server에서의 순위함수들(RANK, DENSE_RANK, ROW_NUMBER, NTILE)에 대해서 알아보며 함께 PARTITION BY 절에 대해서도 함께 알아보도록 하겠습니다.



이번 실습 또한 과거 글에서 만들었던 SampleDB를 통해 진행하도록 하겠습니다.


SELECT * FROM employee;



먼저 RANK, DENSE_RANK, ROW_NUMBER 세가지 함수에 대해서 알아보겠습니다. 먼저 각각의 함수에 대해 간략한 설명과 함께 쿼리를 통해 결과를 확인해보고 세가지 함수의 차이에 대해서 함께 알아보도록 하겠습니다.



1. RANK


RANK 함수는 중복 값들에 대해서 동일 순위로 표시하고, 중복 순위 다음 값에 대해서는 중복 개수만큼 떨어진 순위로 출력하도록 하는 함수 입니다.


SELECT empNo, empName, salary,

RANK() OVER (ORDER BY salary DESC) RANK등수

FROM employee;




2. DENSE_RANK


DENSE_RANK 함수는 중복 값들에 대해서 동일 순위로 표시하고, 중복 순위 다음 값에 대해서는 중복 값 개수와 상관없이 순차적인 순위 값을 출력하도록 하는 함수 입니다.


SELECT empNo, empName, salary,

DENSE_RANK() OVER (ORDER BY salary DESC) DENSE_RANK등수

FROM employee;




3. ROW_NUMBER


ROW_NUMBER 함수는 중복 값들에 대해서도 순차적인 순위를 표시하도록 출력하는 함수 입니다.


SELECT empNo, empName, salary,

ROW_NUMBER() OVER (ORDER BY salary DESC) ROW_NUMBER등수

FROM employee;




4. RANK / DENSE_RANK / ROW_NUMBER


위에서 3가지 함수에 대해서 각각 알아보았습니다.

크게 어려운 내용들은 아니기에 각 함수에 대한 설명과 쿼리문 그리고 그에 대한 결과를 보여드렸습니다.

하지만 세가지 함수의 차이에 대해서는 약간 헷갈릴 수 있기에 이번에는 3가지 함수를 동시에 사용해서 차이를 비교해보도록 하겠습니다.


SELECT empNo, empName, salary,

RANK() OVER (ORDER BY salary DESC) RANK등수,

DENSE_RANK() OVER (ORDER BY salary DESC) DENSE_RANK등수,

ROW_NUMBER() OVER (ORDER BY salary DESC) ROW_NUMBER등수

FROM employee;



세가지 함수의 차이를 고려하려면 위 결과의 빨간색 박스를 보면 됩니다.

salary 값이 500으로 중복된 행이 총 3개 존재합니다.


먼저 RANK함수는

중복 값에 대해서 동일한 순위 그리고

중복 값 다음 값에 대해서 중복순위 + 중복값 개수 의 순위를 출력합니다.


DENSE_RANK함수는

중복 값에 대해서 동일한 순위 그리고

중복 값 다음 값에 대해서 중복순위 + 1 의 순위를 출력합니다.


ROW_NUMBER함수는

중복 값에 대해서 순차적인 순위 그리고

중복 값 다음 값에 대해서 또한 순차적인 순위를 출력합니다.



5. NTILE


NTILE 함수도 순위함수로 사용되지만 위에서 사용된 함수들과는 약간 다르게 느껴질 수 있습니다.

NTILE함수는 뒤에 함께 적어주는 숫자 만큼으로 등분을 하는 함수 입니다.

만약 직원들 데이터에 대해서 salary 순서를 기준으로 4등분을 하고자 한다면 다음과 같습니다.


SELECT empNo, empName, salary,

NTILE(4) OVER (ORDER BY salary DESC) NTILE등분

FROM employee;





6. PARTITION BY


PARTITION BY 절 또한 어렵지 않습니다.

만약 위와 같은 데이터에서 단순히 모든 사람의 salary를 순위 매기고 싶은 것이 아니라, 직급별 순위를 매기고 싶다면 어떻게 할까요?

직급 별로 구분을 해서 순위를 매기면 됩니다. 이렇게 특정 속성 별로 구분을 하고자 할 때 PARTITION BY절을 사용하면 됩니다.


SELECT empName, job, salary,

RANK() OVER (PARTITION BY job ORDER BY salary DESC) RANK등수

FROM employee;



728x90