DENSE_RANK 창 함수는 OVER 절의 ORDER BY 표현식을 기준으로 값 그룹에 속한 값의 순위를 결정합니다. PARTITION BY 절(옵션)이 존재하면 각 행 그룹의 순위가 재설정됩니다. 순위 기준 값이 같은 행은 순위도 동일하게 결정됩니다. DENSE_RANK 함수는 한 가지 측면에서 RANK와 다릅니다. 즉 2개 이상의 행에서 순위가 동일하면 순위 값의 순서에서도 빈 자리가 없습니다. 예를 들어 두 행의 순위가 1
로 결정되면 다음 순위는 2
입니다.
순위 함수에서는 동일한 쿼리라고 해도 PARTITION BY 절과 ORDER BY 절을 다르게 사용할 수 있습니다.
구문
DENSE_RANK() OVER ( [ PARTITION BY expr_list ] [ ORDER BY order_list ] )
인수
- ( )
-
함수에 인수가 없지만 빈 괄호가 필요합니다.
- OVER
-
DENSE_RANK 함수의 창 절입니다.
- PARTITION BY expr_list
-
(선택) 창을 정의하는 하나 이상의 표현식입니다.
- ORDER BY order_list
-
(선택) 순위 값의 기준이 되는 표현식입니다. PARTITION BY를 지정하지 않으면 ORDER BY가 전체 테이블을 사용합니다. 즉 ORDER BY가 생략되면 모든 행의 반환 값은
1
입니다.ORDER BY에서 고유한 순서를 지정하지 않으면 행의 순서는 비확정적입니다. 자세한 내용은 창 함수 데이터에 대한 고유 순서 지정 섹션을 참조하세요.
반환 타입
BIGINT
예시
다음 예제에서는 창 함수에 대한 샘플 테이블을 사용합니다. 자세한 내용은 창 함수 예제를 위한 샘플 테이블 섹션을 참조하세요.
다음 예에서는 판매 수량으로 테이블을 정렬하고 각 행에 밀집 순위와 정규 순위를 모두 할당합니다. 결과는 창 함수 결과를 적용한 후에 정렬됩니다.
SELECT salesid, qty,
DENSE_RANK() OVER(ORDER BY qty DESC) AS d_rnk,
RANK() OVER(ORDER BY qty DESC) AS rnk
FROM winsales
ORDER BY 2,1;
+---------+-----+-------+-----+
| salesid | qty | d_rnk | rnk |
+---------+-----+-------+-----+
| 10001 | 10 | 5 | 8 |
| 10006 | 10 | 5 | 8 |
| 30001 | 10 | 5 | 8 |
| 40005 | 10 | 5 | 8 |
| 30003 | 15 | 4 | 7 |
| 20001 | 20 | 3 | 4 |
| 20002 | 20 | 3 | 4 |
| 30004 | 20 | 3 | 4 |
| 10005 | 30 | 2 | 2 |
| 30007 | 30 | 2 | 2 |
| 40001 | 40 | 1 | 1 |
+---------+-----+-------+-----+
동일한 쿼리에서 DENSE_RANK와 RANK 함수를 함께 사용하여 같은 행 집합에 할당되는 순위의 차이를 기록합니다.
다음 예제에서는 sellerid를 기준으로 테이블을 분할하고, 각 분할을 수량별로 정렬하고, 각 행에 고밀도 순위를 할당합니다. 결과는 창 함수 결과를 적용한 후에 정렬됩니다.
SELECT salesid, sellerid, qty,
DENSE_RANK() OVER(PARTITION BY sellerid ORDER BY qty DESC) AS d_rnk
FROM winsales
ORDER BY 2,3,1;
+---------+----------+-----+-------+
| salesid | sellerid | qty | d_rnk |
+---------+----------+-----+-------+
| 10001 | 1 | 10 | 2 |
| 10006 | 1 | 10 | 2 |
| 10005 | 1 | 30 | 1 |
| 20001 | 2 | 20 | 1 |
| 20002 | 2 | 20 | 1 |
| 30001 | 3 | 10 | 4 |
| 30003 | 3 | 15 | 3 |
| 30004 | 3 | 20 | 2 |
| 30007 | 3 | 30 | 1 |
| 40005 | 4 | 10 | 2 |
| 40001 | 4 | 40 | 1 |
+---------+----------+-----+-------+
마지막 예제를 성공적으로 사용하려면 다음 명령을 사용하여 WINSALES 테이블에 행을 삽입합니다. 이 행은 다른 행과 동일한 buyerid, sellerid 및 qtysold를 가집니다. 이렇게 하면 마지막 예제에서 두 행이 동점이 되므로 DENSE_RANK와 RANK 함수의 차이점이 표시됩니다.
INSERT INTO winsales VALUES(30009, '2/2/2003', 3, 'b', 20, NULL);
다음 예제에서는 buyerid 및 sellerid를 기준으로 테이블을 분할하고, 각 분할을 수량별로 정렬하고, 각 행에 밀도 순위와 일반 순위를 모두 할당합니다. 결과는 창 함수가 적용된 후 정렬됩니다.
SELECT salesid, sellerid, qty, buyerid,
DENSE_RANK() OVER(PARTITION BY buyerid, sellerid ORDER BY qty DESC) AS d_rnk,
RANK() OVER (PARTITION BY buyerid, sellerid ORDER BY qty DESC) AS rnk
FROM winsales
ORDER BY rnk;
+---------+----------+-----+---------+-------+-----+
| salesid | sellerid | qty | buyerid | d_rnk | rnk |
+---------+----------+-----+---------+-------+-----+
| 20001 | 2 | 20 | b | 1 | 1 |
| 30007 | 3 | 30 | c | 1 | 1 |
| 10006 | 1 | 10 | c | 1 | 1 |
| 10005 | 1 | 30 | a | 1 | 1 |
| 20002 | 2 | 20 | c | 1 | 1 |
| 30009 | 3 | 20 | b | 1 | 1 |
| 40001 | 4 | 40 | a | 1 | 1 |
| 30004 | 3 | 20 | b | 1 | 1 |
| 10001 | 1 | 10 | c | 1 | 1 |
| 40005 | 4 | 10 | a | 2 | 2 |
| 30003 | 3 | 15 | b | 2 | 3 |
| 30001 | 3 | 10 | b | 3 | 4 |
+---------+----------+-----+---------+-------+-----+