问题
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