繁体   English   中英

根据行的数值更新

[英]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.rankr.correction保留您要添加到“ Points字段中的玩家的排名(点数/位置,从5到1)。 如果玩家拥有相同的Conqueror ,则校正代表对这些值的校正,并且即使排名为2和3,我们也需要给出相同的点数,但是对于第二名玩家,添加的点数将是相同的等级= 4 +校正= 0第三名玩家的等级= 3 +修正= 1

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM