All about Oracle Technologies

Saturday, 14 February 2015

Cách sử dụng hàm ROW_NUMBER, RANK và DENSE_RANK

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:
  • 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 đó

2 comments :