Đây là một giải pháp thay thế:không lưu trữ thứ hạng nào cả! :-)
Bạn có thể tính toán chúng một cách nhanh chóng.
Ví dụ:
SELECT id, (@next_rank := IF(@score <> score, 1, 0)) nr,
(@score := score) score, (@r := IF(@next_rank = 1, @r + 1, @r)) rank
FROM rank, (SELECT @r := 0) dummy1
ORDER BY score DESC;
Kết quả:
+------+----+-------+------+
| id | nr | score | rank |
+------+----+-------+------+
| 2 | 1 | 23 | 1 |
| 4 | 1 | 17 | 2 |
| 1 | 0 | 17 | 2 |
| 5 | 1 | 10 | 3 |
| 3 | 1 | 2 | 4 |
+------+----+-------+------+
nr
đây là cột phụ trợ cho biết liệu chúng ta có nên chỉ định thứ hạng tiếp theo hay không.
Bạn có thể bọc truy vấn này trong một select
khác và thực hiện phân trang, chẳng hạn.
SELECT id, score, rank
FROM (SELECT id, (@next_rank := IF(@score <> score, 1, 0)) nr,
(@score := score) score, (@r := IF(@next_rank = 1, @r + 1, @r)) rank
FROM rank, (SELECT @r := 0) dummy1
ORDER BY score DESC) t
WHERE rank > 1 and rank < 3;
Kết quả:
+------+-------+------+
| id | score | rank |
+------+-------+------+
| 4 | 17 | 2 |
| 1 | 17 | 2 |
+------+-------+------+
THẬN TRỌNG :kể từ bây giờ rank
là một cột được tính toán, bạn không thể lập chỉ mục nó và trang một cách hiệu quả vào tập dữ liệu (nghĩa là "chọn các bản ghi có xếp hạng từ 3000 đến 3010"). Nhưng nó vẫn tốt cho "chọn N xếp hạng hàng đầu" (miễn là bạn đặt LIMIT
tương ứng trên một truy vấn)