Giả sử bạn đang thiết kế một ứng dụng cơ sở dữ liệu SQL Server cho Giám đốc điều hành của công ty và bạn phải hiển thị nhân viên được trả lương cao thứ năm trong công ty.
Bạn sẽ làm gì? Một giải pháp là viết một truy vấn như sau:
SELECT EmployeeName FROM Employees ORDER BY Salary DESC OFFSET 4 ROWS FETCH FIRST 1 ROWS ONLY;
Truy vấn trên có vẻ phức tạp, đặc biệt nếu bạn phải xếp hạng tất cả các nhân viên. Trong trường hợp đó, một giải pháp là liệt kê các nhân viên theo thứ tự lương giảm dần và sau đó lấy chỉ số của nhân viên đó làm cấp bậc. Tuy nhiên, mọi thứ sẽ trở nên phức tạp nếu nhiều nhân viên có cùng mức lương. Bạn sẽ xếp hạng chúng như thế nào?
May mắn thay, SQL Server đi kèm với các chức năng xếp hạng tích hợp có thể được sử dụng để xếp hạng các bản ghi theo nhiều cách khác nhau. Trong bài viết này, chúng tôi sẽ giới thiệu chi tiết các chức năng xếp hạng máy chủ SQL minh họa nó bằng các ví dụ.
Có bốn loại chức năng xếp hạng khác nhau trong SQL Server:
- Xếp hạng ()
- Dense_Rank ()
- Số hàng ()
- Ntile ()
Điều quan trọng cần đề cập là tất cả các chức năng xếp hạng trong máy chủ SQL đều yêu cầu mệnh đề ORDER BY.
Trước khi xem xét chi tiết từng chức năng xếp hạng, trước tiên, chúng ta hãy tạo dữ liệu giả mà chúng tôi sẽ sử dụng trong bài viết này để giải thích chức năng xếp hạng. Thực thi tập lệnh sau:
CREATE DATABASE Showroom Use Showroom CREATE TABLE Car ( CarId int identity(1,1) primary key, Name varchar(100), Make varchar(100), Model int , Price int , Type varchar(20) ) insert into Car( Name, Make, Model , Price, Type) VALUES ('Corrolla','Toyota',2015, 20000,'Sedan'), ('Civic','Honda',2018, 25000,'Sedan'), ('Passo','Toyota',2012, 18000,'Hatchback'), ('Land Cruiser','Toyota',2017, 40000,'SUV'), ('Corrolla','Toyota',2011, 17000,'Sedan'), ('Vitz','Toyota',2014, 15000,'Hatchback'), ('Accord','Honda',2018, 28000,'Sedan'), ('7500','BMW',2015, 50000,'Sedan'), ('Parado','Toyota',2011, 25000,'SUV'), ('C200','Mercedez',2010, 26000,'Sedan'), ('Corrolla','Toyota',2014, 19000,'Sedan'), ('Civic','Honda',2015, 20000,'Sedan')
Trong đoạn script trên, chúng ta tạo cơ sở dữ liệu Showroom với một bảng Car. Bảng Xe có năm thuộc tính:Xe, Tên, Kiểu dáng, Mẫu, Giá và Loại.
Tiếp theo, chúng tôi đã thêm 12 bản ghi giả trong bảng Xe hơi.
Bây giờ, bạn sẽ thấy từng chức năng xếp hạng.
1. Chức năng Xếp hạng
Hàm xếp hạng trong máy chủ SQL chỉ định thứ hạng cho từng bản ghi được sắp xếp theo mệnh đề ORDER BY. Ví dụ:nếu bạn muốn xem chiếc xe hơi đắt thứ năm trong bảng Xe hơi, bạn có thể sử dụng hàm xếp hạng như sau:
Use Showroom SELECT Name,Make,Model, Price, Type, RANK() OVER(ORDER BY Price DESC) as PriceRank FROM Car
Trong tập lệnh ở trên, hãy chọn Tên, Kiểu dáng, Mẫu, Giá, Loại và xếp hạng của từng chiếc xe được đặt hàng theo Giá dưới dạng cột "Giá". Cú pháp cho chức năng Xếp hạng rất đơn giản. Bạn phải viết hàm RANK theo sau là toán tử OVER. Bên trong toán tử OVER, bạn cần chuyển mệnh đề ORDER BY để sắp xếp dữ liệu. Đầu ra của tập lệnh ở trên trông giống như sau:
Bạn có thể xem thứ hạng cho từng chiếc xe. Điều quan trọng cần đề cập là nếu có sự ràng buộc giữa thứ hạng của hai kỷ lục, thì vị trí xếp hạng tiếp theo sẽ bị bỏ qua. Ví dụ, có sự ràng buộc giữa bản ghi 5 và 6 trong đầu ra. Cả Parado và Civic đều có giá ngang nhau và do đó cùng xếp thứ 5. Tuy nhiên, thứ hạng tiếp theo, cụ thể là hạng 6 bị bỏ qua và hai chiếc tiếp theo trong danh sách được xếp hạng 7 vì chúng cũng có cùng mức giá. Sau hạng 7, hạng 8 lại bị bỏ qua và hạng tiếp theo được chỉ định là 9.
Bạn có thể chia dữ liệu thành các phân vùng và sau đó áp dụng xếp hạng cho các phân vùng riêng lẻ. Trong tập lệnh sau, có phân vùng của các bản ghi theo loại. Chúng tôi xếp hạng những chiếc xe bên trong mỗi phân vùng.
SELECT Name,Make,Model, Price, Type, RANK() OVER(PARTITION BY Type ORDER BY Price DESC) as PriceRank FROM Car
Đầu ra của tập lệnh ở trên trông giống như sau:
Rõ ràng là từ đầu ra rằng các bản ghi đã được phân vùng theo loại ô tô và cấp bậc đã được chỉ định cục bộ bên trong phân vùng. Ví dụ:hai bản ghi đầu tiên thuộc phân vùng “Hatchback” và đã được xếp hạng 1 và 2. Đối với phân vùng tiếp theo, tức là “Sedan”, thứ hạng được đặt lại thành 1.
2. Hàm Dense_Rank
Hàm thick_rank tương tự như hàm rank. Tuy nhiên, trong trường hợp secure_rank, nếu có sự ràng buộc giữa hai bản ghi về thứ hạng, thì thứ hạng tiếp theo sẽ không bị bỏ qua. Hãy xem chứng minh điều đó với ví dụ. Thực thi tập lệnh sau:
Use Showroom SELECT Name,Make,Model, Price, Type, DENSE_RANK() OVER(ORDER BY Price DESC) as DensePriceRank FROM Car
Một lần nữa, bạn có thể thấy rằng bản ghi thứ 5 và thứ 6 có cùng giá trị cho Giá và cả hai đều đã được chỉ định xếp hạng 5. Tuy nhiên, không giống như hàm xếp hạng đã bỏ qua xếp hạng tiếp theo, hàm bold_rank không bỏ qua xếp hạng tiếp theo và xếp hạng 6 đã được chỉ định cho bản ghi tiếp theo.
Giống như hàm xếp hạng, hàm bold_rank cũng có thể được áp dụng cho phân vùng theo mệnh đề. Xem tập lệnh sau:
SELECT Name,Make,Model, Price, Type, DENSE_RANK() OVER(PARTITION BY Type ORDER BY Price DESC) as DensePriceRank FROM Car
Đầu ra của tập lệnh ở trên trông giống như sau:
3. Hàm Row_Number
Hàm row_number cũng xếp hạng các bản ghi theo các điều kiện được chỉ định bởi mệnh đề ORDER BY. Tuy nhiên, không giống như các hàm rank và bold_rank, hàm row_number không chỉ định cùng một thứ hạng khi có các giá trị trùng lặp cho cột được chỉ định bởi mệnh đề ORDER BY. Xem tập lệnh sau:
SELECT Name,Make,Model, Price, Type, DENSE_RANK() OVER(PARTITION BY Type ORDER BY Price DESC) as DensePriceRank FROM Car
Đầu ra của tập lệnh ở trên trông giống như sau:
Từ tập lệnh ở trên, bạn có thể thấy rằng cả bản ghi thứ 5 và thứ 6 đều có cùng giá trị cho cột Giá, nhưng thứ hạng được gán cho chúng là khác nhau.
Tương tự, hàm row_number có thể được áp dụng cho dữ liệu được phân vùng. Hãy xem đoạn mã sau đây chẳng hạn.
SELECT Name,Make,Model, Price, Type, ROW_NUMBER() OVER(PARTITION BY Type ORDER BY Price DESC) AS PriceRankRow FROM Car
Đầu ra của tập lệnh ở trên trông giống như sau:
4. Hàm NTILE
Hàm NTILE nhóm xếp hạng. Giả sử bạn có 12 bản ghi trong một bảng và bạn muốn xếp chúng thành nhóm 4. Ba bản ghi đầu tiên sẽ có thứ hạng 1, ba bản ghi tiếp theo sẽ có thứ hạng 2, v.v.
Hãy xem một ví dụ về hàm NTILE.
Use Showroom SELECT Name,Make,Model, Price, Type, NTILE(4) OVER(ORDER BY Price DESC) as NtilePrice FROM Car
Trong đoạn mã trên, chúng ta đã chuyển 4 làm tham số cho hàm NTILE. Vì chúng tôi có 12 bản ghi, bạn sẽ thấy tổng cộng 4 thứ hạng khác nhau, trong đó 1 thứ hạng sẽ được gán cho ba bản ghi. Đầu ra trông giống như sau:
Bạn có thể thấy rằng ba chiếc xe đắt nhất đầu tiên được xếp hạng 1, ba chiếc tiếp theo được xếp hạng 2, v.v.
Hàm NTILE cũng có thể được áp dụng cho dữ liệu được phân vùng. Xem tập lệnh sau:
SELECT Name,Make,Model, Price, Type, NTILE(4) OVER(PARTITION BY Type ORDER BY Price DESC) as NtilePrice FROM Car
Kết luận
Các hàm xếp hạng trong SQL Server được sử dụng để xếp hạng dữ liệu theo nhiều cách khác nhau. Trong bài đọc này, chúng tôi đã giới thiệu các loại chức năng xếp hạng khác nhau với các ví dụ. Các hàm rank và bold_rank cung cấp cùng một thứ hạng cho dữ liệu có cùng giá trị trong mệnh đề ORDER BY trong khi hàm row_number xếp hạng bản ghi theo cách tăng dần ngay cả khi có sự ràng buộc.
Trong trường hợp không có bản ghi trùng lặp nào trong cột được chỉ định bởi mệnh đề ORDER BY, các hàm rank, secure_rank và row_number hoạt động theo cách tương tự.