[MySQL] 행의 순위를 만드는 함수 RANK, DENSE_RANK, ROW_NUMBER(),

생각하는 마리오네트·2022년 2월 23일
1

SQL

목록 보기
34/39

쿼리를 하다보면 행의 순위를 매겨야 하거나, 행과 행간의 관계를 정의하기 위해서 행들의 순서가 필요한 경우가 많이 있습니다. 이럴때 사용 할 수 있는 윈도우함수(행과 행간의 관계를 쉽게 정의하기 위해 만든 함수)에 대해서 간략하게 알아보겠습니다.

간단하게 아래와 같은 데이터가 있다고 생각해 봅시다.

TeamNameSalary
데이터팀마리오3,000
데이터팀네트3,200
기획팀코드3,600
마케팅팀스테이츠3,600

차이점 비교(NONE PARTITION BY)

먼저 RANK 함수 사용 방법은 다음과 같습니다.

# colName : 컬럼명
RANK() OVER ( [PARTITION BY colName1 ] ORDER BY colName2 [DESC] )

여기서 만약에 아래와 같은 식을 넣으면 어떻게 될까요??(PARTITION BY 제외)

SELECT Name, RANK() OVER (ORDER BY salary) AS salaryRanking FROM Salary;

결과는 아래와 같이 나오게 됩니다.

NamesalaryRanking
마리오4
네트3
코드1
스테이츠1

우리가 수식에서 ORDER BY 에 salary를 기준으로 했기때문에 이를 기준으로 순위가 붙는것을 볼 수 있습니다.

그렇다면 DENSE_RANK 와 ROW_NUMBER와의 차이점을 미리 보여드리고 가겠습니다.

똑같이 위의 데이터에 해당 식을 그대로 넣고 RANK()대신 DENSE_RANK 와 ROW_NUMBER를 넣었다고 가정 해 보겠습니다.

DENSE_RANK를 넣는다면 순위는 아래와 같습니다.

NamesalaryRanking
마리오3
네트2
코드1
스테이츠1
  • 즉, 공동 순위를 뛰어넘지 않는다는 점이 RANK와의 차이점입니다.

ROW_NUMBER를 넣는다면 순위는 아래와 같습니다.

NamesalaryRanking
마리오4
네트3
코드2
스테이츠1
  • 즉, 공동 순위가 있을때 아예 무시를 하게 됩니다.

이렇게 세가지의 차이점을 알아 보았습니다. 다음으로 PARTITION BY 를 사용하게 되면 어떻게 다른지 알아보겠습니다.

PARTITION BY 사용하기

앞에서 " ORDER BY salary " 를 사용하여 salary 기준으로 순서를 매기는 것을 확인했습니다. 이제 다음과 같은 경우가 있을 수 있습니다. "이번에는 salary에 따라서 순서를 부여할건데 부서별로 다르게 순서를 배치하고 싶어!!"

이럴경우 사용할 수 있는것이 PARTITION BY 입니다.

아래와 같이 코드를 바꾸어 보겠습니다. 그리고 편의상 원본 테이블을 먼저 첨부하겠습니다.

TeamNameSalary
데이터팀마리오3,000
데이터팀네트3,200
기획팀코드3,600
마케팅팀스테이츠3,600
SELECT name, RANK() OVER(PARTITION BY Team ORDER BY salary DESC) AS salaryRanking FROM Salary;
NamesalaryRanking
마리오2
네트1
코드1
스테이츠1

이렇게 위와 같이 결과가 나옵니다. 이유는 " PARTITION BY Team" 수식을 넣어 주었기 때문에 Team별로 각각 순위를 만들게 됩니다. 이렇게 활용할 수 있고 이번 예시 테이블의 경우 DENSE_RANK와 ROW_NUMBER모두 같은 결과가 나올 거라는 것을 짐작할 수 있습니다.

profile
문제를해결하는도구로서의"데이터"

0개의 댓글