我有一个拥有12万玩家的数据库。每个条目都包含id,score(和更多)。 我们的目标是得到一个不是顶级球员的高分榜,而不是球员上方和下方的N名球员,给出他的身份证。
我目前尝试使用两个查询解决此问题。
查询1:
SELECT (
SELECT COUNT(*)
FROM players p2
WHERE p2.score > p1.score
) AS rank
FROM players p1
WHERE id = ID
返回玩家的等级RANK,偏移量为-1。 (对于最好的球员,它将返回0)
查询2:
SELECT id, score
FROM players
ORDER BY score DESC
LIMIT X OFFSET RANK;
返回一个X = 2 * N + 1个条目的列表。我将$ rank换成-n让中间正在执行请求的玩家(n个玩家更高,当前玩家,n个玩家在下面)。
到目前为止,非常好。
现在的实际问题是,对于某些分数,有更多的玩家得分比X大,这有时会导致应该位于列表中间的玩家甚至不包含在X条目中,但是在上面或下面的一些条目中。
对我而言似乎是一致性问题,查询1返回玩家Z的等级Y,但查询2没有玩家Z在其第Y个位置。
这些查询可以合并,还是有其他好的解决方案?
如果上述说法不明确,那么这是一个极简主义的例子:
n=1, requesting player called: C
database: A:123, B:123, C:123, D:123
Query 1 returns rank 3 for player C
Query 2 returns A:123, B:123, D:123 (being ranks 2-4)
C:123 should be in the middle, but the sorting of query 2 had C as rank 1.
The order of the elements with the same score in query 2 seems randomly
答案 0 :(得分:-1)
您可以使用类似于以下查询的内容获取高分榜中的排名(位置):
select * from (
select @rank:=@rank+1 rank, p.id
from players p
order by score desc
) t, (select @rank:= 0) t2
where id = :UID
在此查询之后,您可以将外部选择更改为仅在“等级”范围内获得等级+ - N