我有一个排名,每 X 次都有一个余额添加到每个玩家的总分中,从而改变他们的排名方式。 我希望我的排名在 DB (MySQL) 上计算,但我希望它高效,所以首先,这里是 BalanceIn 代码:
问题 1:
UPDATE playerscore
SET points = points * 0.9 + GREATEST(-100, LEAST(100, balance)),
balance = 0;
一旦他们的points
都更新了,我想重新排序排名(只针对排名玩家),像这样:
问题 2:
SET @r = 0;
UPDATE playerscore p
INNER JOIN
(SELECT @r:=@r+1 as new_rank, player_id
FROM playerscore
WHERE is_ranked = 1
ORDER BY points DESC) s
ON p.player_id = s.player_id
SET p.rank = s.new_rank
WHERE is_ranked = 1;
它有效,并解决了我的问题,但是:这是要进行 1 次选择,然后从这里更新所有值,还是会为每个玩家得分行进行一次选择?
在伪代码中,这就是我不想要的:
foreach PlayerScore p in playescore
new = get_all_players_sorted
update p.rank = new.new_rank where p.player_id = new.player_id
endforeach
对于 N 个玩家来说:N 选择 + N 更新。 我希望它是:1 选择 + N 更新(包含在单个更新中),如下所示:
new = get_all_players_sorted
foreach PlayerScore p in playescore
update p.rank = new.new_rank where p.player_id = new.player_id
endforeach
我的查询是否正确(Q2)?
最佳答案
如果这是您的查询,您或许可以通过改写查询和使用索引来加快速度。
你想要的指数是playerscore(is_ranked, points desc)
。查询是:
SET @r = 0;
UPDATE playerscore p
SET p.rank = (@r := @r + 1)
WHERE is_ranked = 1
ORDER BY points desc;
在 MySQL 中,您可以将 order by
与 update
一起使用——只要您不使用 join
。在这种情况下,您不需要 join
,因为您将变量设置为单独的语句。
关于mysql - 使用 SELECT 更新以创建排名(效率),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26057534/