[英]Updating based on numerical value of a row
我需要在MySQL中创建一个点系统,这些点是根据特定列的位置添加的。 示例:有5位玩家,“征服者”行中得分最高的玩家获得5分,第二位获得4分,第三位获得3分,等等。这是一个存储过程,在计算得分时会调用:
BEGIN
select Player_name into @a from Player where Conqueror = (select max(Conqueror) from Player);
select Player_name into @b from Player where Conqueror = (select max(Conqueror) from Player where Player_name != @a);
select Player_name into @c from Player where Conqueror = (select max(Conqueror) from Player where Player_name != @a and Player_name != @b );
select Player_name into @d from Player where Conqueror = (select max(Conqueror) from Player where Player_name != @a and Player_name !=@b and Player_name !=@c);
select Player_name into @e from Player where Conqueror = (select max(Conqueror) from Player where Player_name != @a and Player_name !=@b and Player_name !=@c and Player_name !=@d );
select count(Conqueror) into @playernum from Player;
update Player set Points = Points + @playernum where Player_name = @a;
update Player set Points = Points + @playernum-1 where Player_name = @b;
update Player set Points = Points + @playernum-2 where Player_name = @c;
update Player set Points = Points + @playernum-3 where Player_name = @d;
update Player set Points = Points + @playernum-4 where Player_name = @e;
END
该代码看起来很糟糕,但是除了有得分相同的玩家外,它的工作原理还不错。 在那种情况下,由于两个或多个Player_name被添加到变量中,导致MySQL错误#1172-结果包含多行。 谁能给我一个解决方法的想法?
我没时间玩,想出了一个解决方案,玩家4得到2分而不是3分,但这可能只是在IF语句中增加一点点的一种情况。 但是根据此博客文章:
http://jimmod.com/blog/2008/09/09/displaying-row-number-rownum-in-mysql/
实际上,我将摆脱存储过程,并在一个带有subselect的update语句中完成整个操作。 有点像(完全未经测试!):
update Player set points =
( select points from
( SELECT @rownum:=@rownum-1 'points', Conqueror FROM Player p,
(SELECT @rownum:=6) r
order by Conqueror desc
)
)
如果我猜对了语法,那么应该这样做,将5分配到最高点,将4分配给第二点,依此类推,除非两个玩家的得分相同,一个将得到4,另一个将得到3。 IF语句将解决此问题-我将在有更多时间时查看:)
编辑
万一博客被删除,这就是我指的IF语句:
select IF(@score=p.score, @rownum, @rownum:=@rownum+1) rank2, p.*, (@score:=p.score) dummy from player p,
(SELECT @rownum:=0) x,
(SELECT @score:=0) y
order by score desc limit 10;
如果您不需要将具有相同Conqueror
用户放在同一位置,则可以使用此ONE查询:-)而不是5。
更新的查询已经允许用户拥有相同的Conqueror
值,并且根据您的评论,他们将被授予相同数量的积分:
理想情况下,假设2号和3号选手得分相同。 玩家2获得4分,玩家3也获得4分,但玩家4将获得奖励2分。 因此,当分数相同时,所有玩家都将获得积分,就好像他们是唯一拥有该分数的玩家一样。 –巫毒教
SET @rank = 6;
UPDATE Player
INNER JOIN
(
SELECT player_id,
@rank := @rank-1 as rank,
CASE WHEN @prev = Conqueror
THEN @correction := @correction+1
ELSE @correction := 0
END as correction,
@prev := Conqueror
FROM Player
ORDER BY Conqueror DESC
LIMIT 5
) as r
ON Player.player_id = r.player_id
SET Points = Points + r.rank + r.correction;
而且,如果您需要将具有相同Conqueror
结果的玩家放在同一排名上,请给我更多规则以处理此类情况。
编辑-说明
告诫您,您不了解我的查询中发生了什么,我将尝试解释一下。
因此, @prev
var保留先前执行的顶级玩家的值。
例如,对于排名第二的玩家,它将保留第一位玩家的Conqueror
值。
我们需要比较一下第二名玩家是否具有与第一名相同的分数,以便为他提供与您在评论中要求的分数相同的分数。
r.rank
和r.correction
保留您要添加到“ Points
字段中的玩家的排名(点数/位置,从5到1)。 如果玩家拥有相同的Conqueror
,则校正代表对这些值的校正,并且即使排名为2和3,我们也需要给出相同的点数,但是对于第二名玩家,添加的点数将是相同的等级= 4 +校正= 0第三名玩家的等级= 3 +修正= 1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.