Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Cách RANK () hoạt động trong SQL Server

Trong SQL Server, RANK() hàm trả về thứ hạng của mỗi hàng trong phân vùng của tập kết quả. Thứ hạng của một hàng là một cộng với số bậc đứng trước hàng.

Cú pháp

Cú pháp như sau:

RANK ( ) OVER ( [ partition_by_clause ] order_by_clause )

partition_by_clause Là tùy chọn. Nó chia tập hợp kết quả được tạo ra bởi FROM mệnh đề thành các phân vùng mà hàm được áp dụng. Nếu không được chỉ định, hàm sẽ coi tất cả các hàng của tập kết quả truy vấn là một nhóm duy nhất.

order_by_clause bắt buộc. Nó xác định thứ tự của dữ liệu trước khi chức năng được áp dụng.

Lưu ý rằng OVER mệnh đề thường chấp nhận một rows_or_range_clause , nhưng không thể sử dụng đối số đó với RANK() chức năng.

Ví dụ 1 - Cách sử dụng cơ bản

Dưới đây là một ví dụ cơ bản cho thấy cách sử dụng RANK() chức năng:

SELECT
  AlbumId,
  AlbumName,
  ArtistId,
  RANK() OVER (ORDER BY ArtistId ASC) 'Rank'
FROM Albums;

Kết quả:

+-----------+--------------------------+------------+--------+
| AlbumId   | AlbumName                | ArtistId   | Rank   |
|-----------+--------------------------+------------+--------|
| 1         | Powerslave               | 1          | 1      |
| 7         | Somewhere in Time        | 1          | 1      |
| 8         | Piece of Mind            | 1          | 1      |
| 9         | Killers                  | 1          | 1      |
| 10        | No Prayer for the Dying  | 1          | 1      |
| 2         | Powerage                 | 2          | 6      |
| 19        | All Night Wrong          | 3          | 7      |
| 20        | The Sixteen Men of Tain  | 3          | 7      |
| 12        | Big Swing Face           | 4          | 9      |
| 4         | Ziltoid the Omniscient   | 5          | 10     |
| 5         | Casualties of Cool       | 5          | 10     |
| 6         | Epicloud                 | 5          | 10     |
| 3         | Singing Down the Lane    | 6          | 13     |
| 16        | Long Lost Suitcase       | 7          | 14     |
| 17        | Praise and Blame         | 7          | 14     |
| 18        | Along Came Jones         | 7          | 14     |
| 11        | No Sound Without Silence | 9          | 17     |
| 21        | Yo Wassup                | 9          | 17     |
| 22        | Busted                   | 9          | 17     |
| 13        | Blue Night               | 12         | 20     |
| 14        | Eternity                 | 12         | 20     |
| 15        | Scandinavia              | 12         | 20     |
+-----------+--------------------------+------------+--------+

Trọng tâm chính của chúng tôi là ArtistId Xếp hạng cột. Chúng ta có thể thấy rằng thứ hạng tăng lên mỗi khi ArtistId tăng. Điều này là do tôi đang đặt hàng theo ArtistId nên mỗi nghệ sĩ mới sẽ nhận được một thứ hạng mới.

Khi chúng tôi xem xét Xếp hạng , chúng ta có thể thấy khá nhiều mối quan hệ. Có nghĩa là, khá nhiều hàng có cùng thứ hạng. Điều này có thể xảy ra vì tôi đang đặt hàng theo ArtistId và một số giá trị ArtistId nằm trong nhiều hàng.

Các hàng liên kết này rất hữu ích để chứng minh cách RANK() làm. Như đã đề cập, nó tăng thêm một cộng với số thứ hạng đứng trước nó. Các hàng được ràng buộc khiến khoảng trống xuất hiện trong các giá trị xếp hạng (tức là chúng không phải lúc nào cũng tăng 1). Trong ví dụ trên, có khá nhiều khoảng trống. Đầu tiên là nơi nó đi từ 1 đến 6. Sau đó, một cái khác khi nó đi từ 7 đến 9, v.v.

Nếu bạn không muốn những khoảng trống này, hãy sử dụng DENSE_RANK() , hoạt động theo cùng một cách ngoại trừ không có khoảng trống. Thứ hạng dày đặc được tính bằng một cộng với số phân biệt xếp hạng các giá trị đứng trước hàng đó.

Ví dụ 2 - Phân vùng

Bạn cũng có thể chia kết quả thành các phân vùng. Khi bạn làm điều này, thứ hạng được tính dựa trên mỗi phân vùng (vì vậy nó sẽ bắt đầu lại với mỗi phân vùng mới).

Ví dụ:

SELECT
  Genre,
  AlbumName,
  ArtistId,
  RANK() OVER (PARTITION BY Genre ORDER BY ArtistId ASC) 'Rank'
FROM Albums
INNER JOIN Genres 
ON Albums.GenreId = Genres.GenreId;

Kết quả:

+---------+--------------------------+------------+--------+
| Genre   | AlbumName                | ArtistId   | Rank   |
|---------+--------------------------+------------+--------|
| Country | Singing Down the Lane    | 6          | 1      |
| Country | Yo Wassup                | 9          | 2      |
| Country | Busted                   | 9          | 2      |
| Jazz    | All Night Wrong          | 3          | 1      |
| Jazz    | The Sixteen Men of Tain  | 3          | 1      |
| Jazz    | Big Swing Face           | 4          | 3      |
| Pop     | Long Lost Suitcase       | 7          | 1      |
| Pop     | Praise and Blame         | 7          | 1      |
| Pop     | Along Came Jones         | 7          | 1      |
| Pop     | No Sound Without Silence | 9          | 4      |
| Pop     | Blue Night               | 12         | 5      |
| Pop     | Eternity                 | 12         | 5      |
| Pop     | Scandinavia              | 12         | 5      |
| Rock    | Powerslave               | 1          | 1      |
| Rock    | Somewhere in Time        | 1          | 1      |
| Rock    | Piece of Mind            | 1          | 1      |
| Rock    | Killers                  | 1          | 1      |
| Rock    | No Prayer for the Dying  | 1          | 1      |
| Rock    | Powerage                 | 2          | 6      |
| Rock    | Ziltoid the Omniscient   | 5          | 7      |
| Rock    | Casualties of Cool       | 5          | 7      |
| Rock    | Epicloud                 | 5          | 7      |
+---------+--------------------------+------------+--------+

Trong trường hợp này, tôi phân vùng theo Thể loại. Điều này khiến mỗi hàng chỉ được xếp hạng so với các hàng khác trong cùng một phân vùng. Vì vậy, mỗi phân vùng làm cho giá trị xếp hạng bắt đầu lại từ 1.

Ví dụ 3 - Ví dụ về Bảng điểm

Đây là một trường hợp sử dụng khả thi để hiển thị thứ hạng cho người dùng.

SELECT  
  Player,
  Score,
  RANK() OVER (ORDER BY Score Desc) 'Rank'
FROM Scoreboard;

Kết quả:

+----------+---------+--------+
| Player   | Score   | Rank   |
|----------+---------+--------|
| Bart     | 2010    | 1      |
| Burns    | 1270    | 2      |
| Meg      | 1030    | 3      |
| Marge    | 990     | 4      |
| Lisa     | 710     | 5      |
| Ned      | 666     | 6      |
| Apu      | 350     | 7      |
| Homer    | 1       | 8      |
+----------+---------+--------+

Tuy nhiên, hãy lưu ý rằng bất kỳ kết quả ràng buộc nào cũng sẽ dẫn đến khoảng cách trong các giá trị xếp hạng.

Dưới đây là những gì sẽ xảy ra nếu Lisa bất ngờ khớp với điểm của Bart:

SELECT  
  Player,
  Score,
  RANK() OVER (ORDER BY Score Desc) 'Rank'
FROM Scoreboard;

Kết quả:

+----------+---------+--------+
| Player   | Score   | Rank   |
|----------+---------+--------|
| Lisa     | 2010    | 1      |
| Bart     | 2010    | 1      |
| Burns    | 1270    | 3      |
| Meg      | 1030    | 4      |
| Marge    | 990     | 5      |
| Ned      | 666     | 6      |
| Apu      | 350     | 7      |
| Homer    | 1       | 8      |
+----------+---------+--------+

Trong trường hợp này, không ai được xếp ở vị trí thứ 2, bởi vì hai người chơi đầu tiên đang xếp ở vị trí thứ 1.

Như đã đề cập, nếu bạn cần loại bỏ các khoảng trống như khoảng trống này, hãy sử dụng DENSE_RANK() .

Ví dụ 4 - Thay thế RANK () bằng DENSE_RANK ()

Đây là ví dụ tương tự một lần nữa, ngoại trừ lần này tôi sử dụng DENSE_RANK() :

SELECT  
  Player,
  Score,
  DENSE_RANK() OVER (ORDER BY Score Desc) 'Rank'
FROM Scoreboard;

Kết quả:

+----------+---------+--------+
| Player   | Score   | Rank   |
|----------+---------+--------|
| Lisa     | 2010    | 1      |
| Bart     | 2010    | 1      |
| Burns    | 1270    | 2      |
| Meg      | 1030    | 3      |
| Marge    | 990     | 4      |
| Ned      | 666     | 5      |
| Apu      | 350     | 6      |
| Homer    | 1       | 7      |
+----------+---------+--------+

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. chuyển đổi kiểu dữ liệu varchar thành kiểu dữ liệu datetime dẫn đến giá trị nằm ngoài phạm vi

  2. Làm cách nào để tôi chèn một Byte [] vào một cột VARBINARY của Máy chủ SQL

  3. Cách tạo bảng trong SQL Server

  4. Chèn một chuỗi với các số 0 ở đầu để nó dài 3 ký tự trong SQL Server 2008

  5. Làm cách nào để kiểm tra xem một cột có tồn tại trong bảng SQL Server hay không?