23/08/2019, 08:56

[DATABASE] Hướng dẫn sử dụng hàm ROW_NUMBER, RANK và DENSE_RANK trong Sqlserver

Bài viết hôm nay, mình xin hướng dẫn các bạn sử dụng các hàm: ROW_NUMBER, RANK và DENSE_RANK trong Sqlserver. VD: Chúng ta có yêu cầu như 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ý ...

Bài viết hôm nay, mình xin hướng dẫn các bạn sử dụng các hàm: ROW_NUMBER, RANK và DENSE_RANK trong Sqlserver.

VD: Chúng ta có yêu cầu như 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:

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 RANKDENSE_RANK để thực hiện:

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 RANKDENSE_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 đó

LaptrinhVB via oracletechtalk.blogspot.com

Tags: row_number sqldense_rank sqlserverrank sqlserver
0