쿼리를 하다보면 행의 순위를 매겨야 하거나, 행과 행간의 관계를 정의하기 위해서 행들의 순서가 필요한 경우가 많이 있습니다. 이럴때 사용 할 수 있는 윈도우함수(행과 행간의 관계를 쉽게 정의하기 위해 만든 함수)에 대해서 간략하게 알아보겠습니다.
간단하게 아래와 같은 데이터가 있다고 생각해 봅시다.
Team | Name | Salary |
---|---|---|
데이터팀 | 마리오 | 3,000 |
데이터팀 | 네트 | 3,200 |
기획팀 | 코드 | 3,600 |
마케팅팀 | 스테이츠 | 3,600 |
먼저 RANK 함수 사용 방법은 다음과 같습니다.
# colName : 컬럼명
RANK() OVER ( [PARTITION BY colName1 ] ORDER BY colName2 [DESC] )
여기서 만약에 아래와 같은 식을 넣으면 어떻게 될까요??(PARTITION BY 제외)
SELECT Name, RANK() OVER (ORDER BY salary) AS salaryRanking FROM Salary;
결과는 아래와 같이 나오게 됩니다.
Name | salaryRanking |
---|---|
마리오 | 4 |
네트 | 3 |
코드 | 1 |
스테이츠 | 1 |
우리가 수식에서 ORDER BY 에 salary를 기준으로 했기때문에 이를 기준으로 순위가 붙는것을 볼 수 있습니다.
그렇다면 DENSE_RANK 와 ROW_NUMBER와의 차이점을 미리 보여드리고 가겠습니다.
똑같이 위의 데이터에 해당 식을 그대로 넣고 RANK()대신 DENSE_RANK 와 ROW_NUMBER를 넣었다고 가정 해 보겠습니다.
Name | salaryRanking |
---|---|
마리오 | 3 |
네트 | 2 |
코드 | 1 |
스테이츠 | 1 |
Name | salaryRanking |
---|---|
마리오 | 4 |
네트 | 3 |
코드 | 2 |
스테이츠 | 1 |
이렇게 세가지의 차이점을 알아 보았습니다. 다음으로 PARTITION BY 를 사용하게 되면 어떻게 다른지 알아보겠습니다.
앞에서 " ORDER BY salary " 를 사용하여 salary 기준으로 순서를 매기는 것을 확인했습니다. 이제 다음과 같은 경우가 있을 수 있습니다. "이번에는 salary에 따라서 순서를 부여할건데 부서별로 다르게 순서를 배치하고 싶어!!"
이럴경우 사용할 수 있는것이 PARTITION BY 입니다.
아래와 같이 코드를 바꾸어 보겠습니다. 그리고 편의상 원본 테이블을 먼저 첨부하겠습니다.
Team | Name | Salary |
---|---|---|
데이터팀 | 마리오 | 3,000 |
데이터팀 | 네트 | 3,200 |
기획팀 | 코드 | 3,600 |
마케팅팀 | 스테이츠 | 3,600 |
SELECT name, RANK() OVER(PARTITION BY Team ORDER BY salary DESC) AS salaryRanking FROM Salary;
Name | salaryRanking |
---|---|
마리오 | 2 |
네트 | 1 |
코드 | 1 |
스테이츠 | 1 |
이렇게 위와 같이 결과가 나옵니다. 이유는 " PARTITION BY Team" 수식을 넣어 주었기 때문에 Team별로 각각 순위를 만들게 됩니다. 이렇게 활용할 수 있고 이번 예시 테이블의 경우 DENSE_RANK와 ROW_NUMBER모두 같은 결과가 나올 거라는 것을 짐작할 수 있습니다.