mysql和PHP从点池中为用户分配点并排名

时间:2015-01-25 14:30:50

标签: php mysql ranking

这是一个复杂的问题,我一直试图尽可能只用一个查询来解决,但我一直没有准确地解决这个问题。我在PHP中有一个半解决方案,但这有时会失败。

首先要解释一下情况,我正在构建一种MVP系统。只有排名前三的玩家才能获得积分,这很好,但是当投票中有抽奖时我会遇到问题。

点差将是

1st place 3 points
2nd place 2 points
3rd place 1 point

总积分为5分。目前我在php中有一个递归函数,它主要起作用,它需要剩余的总积分并将其除以剩余的展示位置,我只是想知道这是否可以在单个查询中解决。

所以你可能得到的是

Player 1 = 10 votes
players 2 = 9 votes 
player 3 = 9 votes.

所以这里点数应该是

Player 1 = 3 points
Player 2 = 1.5 points
player 3 = 1.5 points (remaining points in pool divided by 2 players)

无论匹配在哪里,同样适用

再次,如果你有

player 1 = 10 votes
player 2 = 10 votes
player 3 = 9 votes
Player 4 = 9 votes

在上述情况下,点差将是

Player 1 & Player 2 = 2.5 points
Player 3 & Player 4 = 0.5 points

所以我相信我可以用一个递归的php函数做这个,它只是计算一些像remaining_points / players_left这样的东西

由于某些原因,偶尔会失败,最终我希望能够通过单个查询完成此操作,而不必担心通过PHP函数进行抽取。

或者关于如何实现这一目标的任何其他想法?

干杯 丹

  • 编辑1:对于披露这是我很久以前在PHP中编写的一个函数,它主要起作用,但我认为对于stackoverflow的范围来说可能太具体了。它可能有助于描绘图片

    function stpoty_update_standings($round, $season)   {
    global $db;
    
    //Do the calculation to update the standings. We could probably do this without extra storage but will leave it as is for now.
    $player_points = $db->write_query("Select vote, sum(points) as points from ".TABLE_PREFIX."stpoty_votes where round_id=".intval($round)." group by vote order by points DESC");
    $gpoints=3;
    
    while($pps=$db->fetch_array($player_points))    {
    
        $users_run = explode(",", $user_collection);
    
        if(in_array($pps["vote"], $users_run)==false)   {
    
            if($gpoints!='0')   {
                //lets check how many people have these points
                $equal_vote = $db->write_query("Select count(vote) from ".TABLE_PREFIX."stpoty_votes where round_id=".intval($round)." group by vote HAVING sum(points)=".$pps["points"]." order by points DESC LIMIT 1");
                $equal_votes = $db->num_rows($equal_vote);
                //now we have a count we can do what we need to do
                if($equal_votes==1) {
                    //We have one user on this score so we can just update their record, we need to check if they exist to perform the right action
                    $exists = $db->write_query( "SELECT points FROM ".TABLE_PREFIX."stpoty_standings where comp=".intval($season)." and player=".intval($pps["vote"]));
                    $exists = $db->fetch_field($exists, "points");
                    if(!empty($exists)) {
                        stpoty_update_standings_update($pps["vote"], $gpoints, $exists, $season);
                    }   else    {
                        stpoty_update_standings_insert($pps["vote"], $gpoints, $season);
                    }
                    $gpoints = --$gpoints;
                } else if ($equal_votes>=2) {
    
                    //if we have two or more points we need to divide remaining points between them, and null out of the loop
                    if($gpoints=='3') {
    
                            //work out the division of points
                        if($equal_votes==2) {
                            $apoints = "2.5";
                            $gpoints = "1";
                        }   else if ($equal_votes>=3) {
                            $apoints = 5 / $equal_votes;
                            $gpoints = 0;
                        }
                    }   else if ($gpoints=='2') {
                        //work out the division of points
                        $apoints = 3 / $equal_votes;
                        $gpoints = 0;
                    }   else if ($gpoints=='1') {
                        $apoints = 1 / $equal_votes;
                        $gpoints = 0;
                    }
                    $comma = "";    
                    $players_on_points = $db->write_query("Select vote, sum(points) from ".TABLE_PREFIX."stpoty_votes where round_id=".intval($round)." group by vote Having sum(points)=".$pps["points"]." order by points DESC");
    
                    while($pop=$db->fetch_array($players_on_points))    {
    
                        $exist = $db->write_query( "SELECT points FROM ".TABLE_PREFIX."stpoty_standings where comp=".intval($season)." and player=".intval($pop["vote"]));
                        $exists = $db->fetch_field($exist, "points");
                        $user_collection .= $comma.$pop["vote"];
                        if(!empty($exists)) {
    
                            stpoty_update_standings_update($pop["vote"], $apoints, $exists, $season);
                        }   else    {
    
                            stpoty_update_standings_insert($pop["vote"], $apoints, $season);
                        }
                        $comma = ",";
                    }
    
                }
            }
        }
    }
    }
    

0 个答案:

没有答案