Bài viết này sẽ hướng dẫn cách sử dụng hàm ROW_NUMBER, RANK và DENSE_RANK.
Xét các yêu cầu sau:
Với yêu cầu 1, ta có bảng kết quả sau:
Và đây là câu SELECT kết hợp với ROW_NUMBER để thực hiện:
Với yêu cầu số 2, ta có bảng kết quả sau:
Và đây là câu SELECT kết hợp với RANK và DENSE_RANK để thực hiện:
Nhìn vào kết quả trên ta thấy rằng kết quả của hàm RANK và DENSE_RANK có những điểm như sau:
Xét các yêu cầu sau:
- Lấy danh sách nhân viên dựa vào ngày ký hợp đồng cho biết nhân viên đó là người thứ mấy trong phòng được ký hợp đồng
- Lấy danh sách nhân viên dựa vào lương cho biết nhân viên đó xếp hạng thứ mấy trong phòng
Với yêu cầu 1, ta có bảng kết quả sau:
DEPTNO
|
ENAME
|
HIREDATE
|
SAL
|
NUM
|
10
|
CLARK
|
09/06/1981
|
2450
|
1
|
10
|
KING
|
17/11/1981
|
5000
|
2
|
10
|
MILLER
|
23/01/1982
|
1300
|
3
|
20
|
SMITH
|
17/12/1980
|
800
|
1
|
20
|
JONES
|
02/04/1981
|
2975
|
2
|
20
|
FORD
|
03/12/1981
|
3000
|
3
|
20
|
SCOTT
|
09/12/1982
|
3000
|
4
|
20
|
ADAMS
|
12/01/1983
|
1100
|
5
|
30
|
ALLEN
|
20/02/1981
|
1600
|
1
|
30
|
WARD
|
22/02/1981
|
1250
|
2
|
30
|
BLAKE
|
01/05/1981
|
2850
|
3
|
30
|
TURNER
|
08/09/1981
|
1500
|
4
|
30
|
MARTIN
|
28/09/1981
|
1250
|
5
|
30
|
JAMES
|
03/12/1981
|
950
|
6
|
Và đây là câu SELECT kết hợp với ROW_NUMBER để thực hiện:
1 2 3 4 5 6 7 | SELECT deptno, ename, hiredate, sal, ROW_NUMBER () OVER (PARTITION BY deptno ORDER BY hiredate) num FROM emp ORDER BY deptno, num; |
Với yêu cầu số 2, ta có bảng kết quả sau:
DEPTNO
|
ENAME
|
HIREDATE
|
SAL
|
RANK_SAL
|
DENSE_RANK_SAL
|
10
|
MILLER
|
1/23/1982
|
1300
|
1
|
1
|
10
|
CLARK
|
6/9/1981
|
2450
|
2
|
2
|
10
|
KING
|
11/17/1981
|
5000
|
3
|
3
|
20
|
SMITH
|
12/17/1980
|
800
|
1
|
1
|
20
|
ADAMS
|
1/12/1983
|
1100
|
2
|
2
|
20
|
JONES
|
4/2/1981
|
2975
|
3
|
3
|
20
|
SCOTT
|
12/9/1982
|
3000
|
4
|
4
|
20
|
FORD
|
12/3/1981
|
3000
|
4
|
4
|
30
|
JAMES
|
12/3/1981
|
950
|
1
|
1
|
30
|
MARTIN
|
9/28/1981
|
1250
|
2
|
2
|
30
|
WARD
|
2/22/1981
|
1250
|
2
|
2
|
30
|
TURNER
|
9/8/1981
|
1500
|
4
|
3
|
30
|
ALLEN
|
2/20/1981
|
1600
|
5
|
4
|
30
|
BLAKE
|
5/1/1981
|
2850
|
6
|
5
|
Và đây là câu SELECT kết hợp với RANK và DENSE_RANK để thực hiện:
1 2 3 4 5 6 7 8 | SELECT deptno, ename, hiredate, sal, RANK () OVER (PARTITION BY deptno ORDER BY sal) rank_sal, DENSE_RANK () OVER (PARTITION BY deptno ORDER BY sal) dense_rank_sal FROM emp ORDER BY deptno; |
Nhìn vào kết quả trên ta thấy rằng kết quả của hàm RANK và DENSE_RANK có những điểm như sau:
- Giống nhau: với những dòng có cùng SAL thì sẽ có cùng hạng
- Khác nhau:
+ Hàm RANK sẽ bỏ qua thứ hạng tiếp theo cho những dòng có cùng hạng trước đó
+ Hàm DENSE_RANK không bỏ qua thứ hạng tiếp theo cho những dòng có cùng hạng trước đó