×

Tính thứ hạng với hàm RANK() trong MySQL

Trong các cơ sở dữ liệu, việc xếp hạng các mục theo một tiêu chí cụ thể là một nhiệm vụ phổ biến. Trong MySQL, mặc dù không có sẵn hàm RANK() như trong một số hệ quản trị cơ sở dữ liệu khác, ta vẫn có thể sử dụng các phương pháp khác để tính toán thứ hạng. Bài viết này sẽ hướng dẫn bạn cách thực hiện điều đó.

Sử dụng Biến Người Dùng (User-Defined Variables)

MySQL hỗ trợ các biến người dùng, cho phép chúng ta tạo ra hành vi tương tự như hàm RANK() của các cơ sở dữ liệu khác.

Ví dụ 1: Tính xếp hạng các sinh viên theo điểm số

Giả sử ta có một bảng students với các cột id, namescore.

+----+-------+-------+
| id | name  | score |
+----+-------+-------+
| 1  | John  | 90    |
| 2  | Alice | 85    |
| 3  | Bob   | 93    |
| 4  | Carol | 85    |
| 5  | Dave  | 60    |
+----+-------+-------+

Chúng ta muốn xếp hạng các sinh viên theo score từ cao xuống thấp.

SET @rank = 0;
SELECT
    id,
    name,
    score,
    (@rank := @rank + 1) AS rank
FROM
    students
ORDER BY
    score DESC;

Kết quả sẽ là:

+----+-------+-------+------+
| id | name  | score | rank |
+----+-------+-------+------+
| 3  | Bob   | 93    | 1    |
| 1  | John  | 90    | 2    |
| 2  | Alice | 85    | 3    |
| 4  | Carol | 85    | 4    |
| 5  | Dave  | 60    | 5    |
+----+-------+-------+------+

Tính Thứ Hạng Với Điều Kiện

Trong trường hợp có các giá trị giống nhau và bạn muốn các giá trị đó được xếp hạng như nhau, phương pháp trên sẽ không hoàn toàn phù hợp. Để xử lý tình huống này, ta cần sử dụng một phương pháp khác.

Ví dụ 2: Xếp hạng các sinh viên với các số điểm giống nhau

SET @rank = 0;
SET @prev_score = NULL;

SELECT
    id,
    name,
    score,
    CASE
        WHEN @prev_score = score THEN @rank
        WHEN @prev_score := score THEN @rank := @rank + 1
        ELSE @rank := @rank + 1
    END AS rank
FROM
    students
ORDER BY
    score DESC;

Kết quả sẽ như sau:

+----+-------+-------+------+
| id | name  | score | rank |
+----+-------+-------+------+
| 3  | Bob   | 93    | 1    |
| 1  | John  | 90    | 2    |
| 2  | Alice | 85    | 3    |
| 4  | Carol | 85    | 3    |
| 5  | Dave  | 60    | 4    |
+----+-------+-------+------+

Sử dụng CTE

Với MySQL 8.0 trở lên, ta có thể sử dụng CTE (Common Table Expressions) để tạo cách tính thứ hạng dễ đọc hơn.

Ví dụ 3: Sử dụng CTE để tính xếp hạng

WITH ranked_students AS (
    SELECT 
        id,
        name,
        score,
        DENSE_RANK() OVER (ORDER BY score DESC) AS rank
    FROM 
        students
)
SELECT * FROM ranked_students;

Kết quả sẽ là:

+----+-------+-------+------+
| id | name  | score | rank |
+----+-------+-------+------+
| 3  | Bob   | 93    | 1    |
| 1  | John  | 90    | 2    |
| 2  | Alice | 85    | 3    |
| 4  | Carol | 85    | 3    |
| 5  | Dave  | 60    | 4    |
+----+-------+-------+------+

Kết Luận

Mặc dù MySQL không có hàm RANK() như một số hệ quản trị cơ sở dữ liệu khác, nhưng nhờ vào các biến người dùng, phương pháp tính với điều kiện và các tính năng của CTE trong MySQL 8.0 trở lên, chúng ta vẫn có thể dễ dàng tính toán thứ hạng cho các bản ghi trong bảng. Hy vọng bài viết này cung cấp cho bạn các giải pháp hữu ích để áp dụng vào dự án thực tế của mình.

Comments