Computer/Database

[SQL] RANK / DENSE_RANK /ROW_NUMBER (순위함수 그리고 최신데이터 출력 방법)

SenJ 2021. 11. 22. 10:13
RANK(), DENSE_RANK(), ROW_NUMBER()

각각 순위/순서를 반환하는 함수이지만 결과는 조금씩 다르다.

RANK는 동점자의 있는 경우 동일 순번을 리턴, 다음 순위는 다음 숫자를 하나를 건너뛴다. (1, 2, 2, 4, 4, 6, .. )

DENSE_RANK는 동점자의 경우에 동일한 순번을 리턴, 다음 순위는 다음 숫자부터 진행이 된다 (1, 2, 2, 3, 3, 4, .. )

ROW_NUMBER의 경우 동점자가 있는 경우에 정렬이 된 순서대로 순서를 반환한다. (1, 2, 3, 4, 5, 6, 7, ...)

아래와 같은 데이터가 있다고 가정해보자.

고객
판매금액
1
24000
2
17000
3
17000
4
14000
5
13500
6
13500
7
13000
SELECT 고객, 
       RANK() OVER (ORDER BY 판매금액 DESC) RANK_EX,
       DENSE_RANK() OVER (ORDER BY 판매금액 DESC) DENSE_RANK_EX,
       ROW_NUMBER() OVER (ORDER BY 판매금액 DESC) ROW_NUMBER_EX
FROM DUAL
 
쿼리의 결과는 아래와 같다
고객
판매금액
RANK_EX
DENSE_RANK_EX
ROW_NUMBER_EX
1
24000
1
1
1
2
17000
2
2
2
3
17000
2
2
3
4
14000
4
3
4
5
13500
5
4
5
6
13500
5
4
6
7
13000
7
5
7

순위를 산정할때에 RANK 또는 DENSE_RANK를 사용하면 유용하다. 그러나 업무중에서 가장 많이 사용했던 함수는 ROW_NUMBER 함수이다.

'PK값(기준값)의 시리얼 데이터 중 가장 최신인 데이터를 가져오고 싶다' 등의 경우 사용하기에 가장 좋은 문법이다.

아래와 같은 데이터가 있다고 가정하자.

고객
시리얼번호
판매금액
1
1
24000
1
2
17000
1
3
17000
2
1
14000
2
2
13500
2
3
13500
2
4
13000
SELECT *
FROM (
    SELECT 고객, 시리얼번호, 판매금액,
           ROW_NUMBER() OVER(PARTITION BY 고객 ORDER BY 시리얼번호 DESC) SEQ
    FROM DUAL
)
WHERE SEQ=1
 
결과값은 아래와 같다.
고객
시리얼번호
판매금액
SEQ
1
3
17000
1
2
4
13000
1

위 쿼리를 통해 기준값(고객)의 시리얼 데이터(순서를 매기고 싶은 값) 중 가장 마지막 데이터(처음이든 마지막이든..) 를 가져올 수 있다.