Data Analytics

윈도우 함수_ 순위함수 RANK, DENSE_RANK, ROW_NUMBER

cheersHena 2022. 12. 16. 01:33
반응형

윈도우 순위 함수에는 RANK, DENSE_RANK, ROW_NUMBER 3가지가 있다. 

 

순위함수 문법)

1. 순위함수() OVER(ODER BY컬럼) -- 컬럼의 순위 
2. 순위함수() OVER(PARTITION BY 컬럼1 ODER BY 컬럼2) -- 컬럼1의 그룹별 컬럼2의 순위

순위함수는 OVER절과 함께 쓰이며 OVER구에는 반드시 ORDER BY절이 들어가야 한다. 

PARTITION 이 없는 경우에는 전체 행을 대상으로 하고, PARTITION이 존재하는 경우 해당 그룹의 행을 대상으로 한다. 

 

1. RANK 함수 

RANK함수에는 반드시 OVER구절에 ODER BY 가 들어가야 한다. ODER BY절의 컬럼을 기준으로 순위를 매기기 때문. 

 

코드로 이해해보자. 

다음과 같은 Employee Table이 있다고 가정하자. 

이때 RANK함수를 써서 가장 높은 salary를 가진 직원의 순위를 매겨보자. 

SELECT * 
      , RANK() OVER(ORDER BY salary DESC) rank
FROM employee

*가장 높은 이기 때문에 내림차순인 DESC를 써주어야 한다. 

 

결과)

결과의 rank를 보면 salary가 높은 순서대로 순위를 매긴것을 볼 수 있다. 

이 때, 90000 의 같은 salary가 공동 1위이기 때문에 해당 데이터를 순위 1로 매기고 

다음 순위를 2가 아닌 3으로 매긴것을 확인할 수 있다. 이것이 바로 RANK함수의 특징이다. 

만약 90000이 한명 더 있었다면 1등이 3개를 차지하기 때문에 다음 순위는 4가 나올 것이다.  

 

하지만 나는 공동 1위가 몇명 있든간에, 다음 순위를 2 -> 3 -> 4 ... 순으로 매기고 싶다. 이럴땐 어떻게 해야할까?

이때 사용할 수 있는 함수가 바로 DENSE_RANK함수이다. 

 

2. DENSE_RANK 함수 

DENSE의 사전적 의미는 '밀집한'이다. 즉 좀 더 순위를 밀집해서 매기는 함수이다. 

같은 데이터에 DENSE_RANK함수를 적용해 보자. 

SELECT * 
      , DENSE_RANK() OVER(ORDER BY salary DESC) dense_rank
FROM employee

결과) 

결과의 dense_rank와 같이 순서대로 순위를 매기는 것을 확인 할 수 있다. 

 

그렇다면 이번에는 공동 순위를 없애고 싶으면 어떻게 할까? 

공동이라 하더라도 90000에 1,2위를 매기고 싶은 경우. 즉, 순위의 중복을 없애고 싶은경우에 쓰는 함수가 ROW_NUMBER이다. 

 

3. ROW_NUMBER함수 

 

SELECT * 
      , ROW_NUMBER() OVER(ORDER BY salary DESC) row_number
FROM employee

결과) 

ROW_NUMBER함수를 사용시 공동 순위에도 1,2로 번호를 매기는 것을 확인 할 수 있다. 

그래서 ROW_NUMBER함수는 주로 순위라기 보다는 이름 그대로 단지 순서 번호를 매길때 사용한다.

 

그렇다면 이번에는 PARTITION을 사용해 보자. 

PARTITION이 적용되어 있지 않으면 순위를 테이블 전체 행에 적용한다.

하지만 예를들어 employee 테이블에서 부서별로 순위를 별도로 매기고 싶을때 PARTITION을 departmentId에 적용하여 

마치 그룹화 시키듯이 만들 수 있다. (단, PARTITION BY 구는 ORDER BY 앞에 사용해주어야한다! )

 

이번에는 3가지 모두의 순위함수를 사용하여 departmentId의 그룹별 salary순위를 매겨보자. 

SELECT * 
      , RANK() OVER(PARTITION BY departmentId ORDER BY salary DESC) rank
      , DENSE_RANK() OVER(PARTITION BY departmentId ORDER BY salary DESC) dense_rank
      , ROW_NUMBER() OVER(PARTITION BY departmentId ORDER BY salary DESC) row_number
FROM employee

결과) 

위와 같이 departmentId가 같은 것끼리 순위를 매긴것을 확인할 수 있다. 

 

 

 

 

 

 

 

 

반응형