这是一个复杂的问题,我一直试图尽可能只用一个查询来解决,但我一直没有准确地解决这个问题。我在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 = ",";
}
}
}
}
}
}