SELECT 用户在 MySQL 上的排名偏移量
SELECT user ranking on MySQL by an offset
我正在尝试在 MySQL 中查询 returns 我只有来自 table 的 10 个用户,但排名值是 xp
栏目。现在我有这个:
SELECT id, xp, @curRank := @curRank + 1 AS rank
FROM usuarios, (SELECT @curRank := 0) r
ORDER BY xp DESC LIMIT 10;
它在获取前 10 个用户时看起来运行良好。
+--------------------+------+------+
| id | xp | rank |
+--------------------+------+------+
| 373901344995803138 | 5863 | 1 |
| 701198768049225770 | 5692 | 2 |
| 239203656405221376 | 4961 | 3 |
| 692489002942726154 | 4508 | 4 |
| 416988898628206593 | 3669 | 5 |
| 312003290378534912 | 3155 | 6 |
| 608344569381126167 | 3059 | 7 |
| 671949142473310238 | 3041 | 8 |
| 549743978191519744 | 2991 | 9 |
| 592440479577145383 | 2519 | 10 |
+--------------------+------+------+
但是当我尝试获取例如 LIMIT 10,10
以获取 11 到 20 之间的用户时,尽管它们是有序的,但它们的全局排名不正确,因为 @curRank
并没有为所有用户增加偏移前。
+--------------------+------+------+
| id | xp | rank |
+--------------------+------+------+
| 638196238436532234 | 1888 | 1 |
| 601269358349516833 | 1447 | 2 |
| 548357514497097743 | 1338 | 3 |
| 203591312031744000 | 1330 | 4 |
| 379034072519016469 | 1283 | 5 |
| 563804445654122497 | 1086 | 6 |
| 421296425981181952 | 1025 | 7 |
| 263816867100098560 | 850 | 8 |
| 631330775379214371 | 776 | 9 |
| 442529076511637504 | 702 | 10 |
+--------------------+------+------+
我不知道如何在使用 LIMIT 时使全球排名发挥作用。
而是使用 row_number()
:
SELECT id, xp, row_number() over (order by cp desc) as rnk
FROM usuarios
ORDER BY xp DESC
LIMIT 10;
在 MySQL 8.0 中,只需使用 window 函数,如 Gordon Linoff 所演示的那样。
在早期版本中,你基本上需要一个子查询来做你想做的事情。我会推荐:
SELECT *
FROM (
SELECT id, xp, @curRank := @curRank + 1 AS rank
FROM (SELECT * FROM usuarios ORDER BY xp DESC) u
CROSS JOIN (SELECT @curRank := 0) r
ORDER BY xp DESC
) t
ORDER BY xp DESC
LIMIT 10, 10;
子查询首先对所有用户进行排名,然后您可以放心地在外部查询中进行过滤。请注意,首先在子查询中通过 xp
查询 pre-orders the table:这更安全(用户变量在 MySQL 中很棘手)。
实际上,您甚至不需要在外部查询中LIMIT
;您可以改用 WHERE
子句:
SELECT *
FROM (
SELECT id, xp, @curRank := @curRank + 1 AS rank
FROM (SELECT * FROM usuarios ORDER BY xp DESC) u
CROSS JOIN (SELECT @curRank := 0) r
ORDER BY xp DESC
) t
WHERE rank BETWEEN 11 AND 20
ORDER BY rank
我正在尝试在 MySQL 中查询 returns 我只有来自 table 的 10 个用户,但排名值是 xp
栏目。现在我有这个:
SELECT id, xp, @curRank := @curRank + 1 AS rank
FROM usuarios, (SELECT @curRank := 0) r
ORDER BY xp DESC LIMIT 10;
它在获取前 10 个用户时看起来运行良好。
+--------------------+------+------+
| id | xp | rank |
+--------------------+------+------+
| 373901344995803138 | 5863 | 1 |
| 701198768049225770 | 5692 | 2 |
| 239203656405221376 | 4961 | 3 |
| 692489002942726154 | 4508 | 4 |
| 416988898628206593 | 3669 | 5 |
| 312003290378534912 | 3155 | 6 |
| 608344569381126167 | 3059 | 7 |
| 671949142473310238 | 3041 | 8 |
| 549743978191519744 | 2991 | 9 |
| 592440479577145383 | 2519 | 10 |
+--------------------+------+------+
但是当我尝试获取例如 LIMIT 10,10
以获取 11 到 20 之间的用户时,尽管它们是有序的,但它们的全局排名不正确,因为 @curRank
并没有为所有用户增加偏移前。
+--------------------+------+------+
| id | xp | rank |
+--------------------+------+------+
| 638196238436532234 | 1888 | 1 |
| 601269358349516833 | 1447 | 2 |
| 548357514497097743 | 1338 | 3 |
| 203591312031744000 | 1330 | 4 |
| 379034072519016469 | 1283 | 5 |
| 563804445654122497 | 1086 | 6 |
| 421296425981181952 | 1025 | 7 |
| 263816867100098560 | 850 | 8 |
| 631330775379214371 | 776 | 9 |
| 442529076511637504 | 702 | 10 |
+--------------------+------+------+
我不知道如何在使用 LIMIT 时使全球排名发挥作用。
而是使用 row_number()
:
SELECT id, xp, row_number() over (order by cp desc) as rnk
FROM usuarios
ORDER BY xp DESC
LIMIT 10;
在 MySQL 8.0 中,只需使用 window 函数,如 Gordon Linoff 所演示的那样。
在早期版本中,你基本上需要一个子查询来做你想做的事情。我会推荐:
SELECT *
FROM (
SELECT id, xp, @curRank := @curRank + 1 AS rank
FROM (SELECT * FROM usuarios ORDER BY xp DESC) u
CROSS JOIN (SELECT @curRank := 0) r
ORDER BY xp DESC
) t
ORDER BY xp DESC
LIMIT 10, 10;
子查询首先对所有用户进行排名,然后您可以放心地在外部查询中进行过滤。请注意,首先在子查询中通过 xp
查询 pre-orders the table:这更安全(用户变量在 MySQL 中很棘手)。
实际上,您甚至不需要在外部查询中LIMIT
;您可以改用 WHERE
子句:
SELECT *
FROM (
SELECT id, xp, @curRank := @curRank + 1 AS rank
FROM (SELECT * FROM usuarios ORDER BY xp DESC) u
CROSS JOIN (SELECT @curRank := 0) r
ORDER BY xp DESC
) t
WHERE rank BETWEEN 11 AND 20
ORDER BY rank