Ranking based on users placement instead of score

南楼画角 提交于 2019-12-25 09:01:07

问题


I have a issue that I cannot wrap my head around.

I am using the Laravel Framework.

I am trying to make a ranking table based on placement (Meaning the user does not have any SCORE, they just have placements)

How I want it to work is the following way:

User A = Placement: 1

User B = Placement: 10

User B wins over User A, then User B gets placed as number 1 and User A gets placed as number 2, and then I want it to update all the other users accordingly.

I can't seem to find a reliable way of doing this.


回答1:


I don't think this is a Laravel challenge but an SQL one. And it may be simple to solve: basically, you will ask for the actual position of the defeated person, if the position is greater than the winner, you do nothing, otherwise you will assign the position of the loser to the new winner and update the rest of the table with a +1 in the position column.

In code it would be something like this:

$winner_player = User::where('id', userA->id)->first();
$loser_player = User::where('id', userB->id)->first();

if($winner_player->position < $loser_player->position) {
     //Update the rest of the users. 
     //We add 2 because we need space for the new winner and for 
     //the loser that is still above of the rest of the players. 
     DB::table('users')
        ->where('position', '>', $loser_player->position)
        ->update(DB::raw('position+2'));

     //Set the winner with the actual position of the loser.
     $winner_player->position = $loser_player->position;
     $winner_player->save();

     //Set the looser with the new position (+1 of his actual).
     $loser_player->position = $loser_player->position + 1; 
     $loser_player->save();
}

UPDATED LOGIC As Classified pointed out, it moves the rows around but doesn't do it correctly, so I'm updating the logic to make it work as it is supposed to, and it will be a little simpler too.

$winner_player = User::where('id', userA->id)->first();
$loser_player = User::where('id', userB->id)->first();

if($winner_player->position < $loser_player->position) {
     //Set the winner with the actual position of the loser.
     $winner_player->position = $loser_player->position;

     //Update the users between the swap. There is no need to update 
     //the whole table, we only update the records between the swap.
     DB::table('users')
        ->where([['position', '<', $winner_player->position],
                 ['position', '>=', $loser_player->position]])
        ->update(DB::raw('position+1'));

     //Save the value of the winner AFTER updating the positions 
     //between winner and loser.
     $winner_player->save();
}


来源:https://stackoverflow.com/questions/45944585/ranking-based-on-users-placement-instead-of-score

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!