Я пытаюсь вычислить ранжирование команды в упорядоченном наборе результатов MySQL, и проблема, с которой я сталкиваюсь, обнаруживает связи для первой команды, которая появляется со связанным значением.
Например, скажем, набор результатов следующий:
team_id pts --------------- 1 89 2 87 3 76 4 76 5 52
Я вычисляю рейтинг команды со следующим PHP:
$i = 0; while($row = mysql_fetch_assoc($r)) { //iterate thru ordered (desc) SQL results ++$i; ($row['pts'] == $prev_val) ? $rnk = 'T-' . $rnk //same as previous score, indicate tie : $rnk = $i; //not same as previous score $rnk = str_replace('TT-','T-',$rnk); //eliminate duplicative tie indicator if ($row['team_id'] == $team_id) { //current team in resultset matches team in question, set team's rank $arr_ranks['tp']['cat'] = 'Total Points'; $arr_ranks['tp']['actual'] = number_format($row['pts'],1); $arr_ranks['tp']['league_rank'] = $rnk; $arr_ranks['tp']['div_rank'] = $div_rnk; } else if ($i == 1) { //current team is category leader (rank=1) and is not team in question, set current team as leader $arr_ranks['tp']['leader'] = "<a href='index.php?view=franchise&team_id=" . $row['team_id'] . "'>" . get_team_name($row['team_id']) . '</a> (' . number_format($row['pts'],1) . ')'; } $prev_val = $row['pts']; //set current score as previous score for next iteration of loop }
Логика «галстука» выше захватит команду № 4 как связанную с командой № 3, но не наоборот .
Другими словами, для команды № 3, $rnk = 3
, а для команды №4 – $rnk = T-3
. (Оба должны быть «Т-3».)
Таким образом, возникает вопрос: как я «смотрю вперед», итерации по результатам, чтобы узнать, является ли текущий счет связующим звеном / дублированием оценок дальше по списку, так что я могу рассматривать его как галстук вместе с последующими обманами?
Благодарю.
EDIT: я могу реализовать код Ignacio, если я сначала храню результаты в таблице, например, "wins"
ниже:
select s1.team_id, t.division_id, sum(s1.score>s2.score) tot_wins, ( select count(*) from wins where team_id <> s1.team_id and wins > (select wins from wins where team_id = s1.team_id) )+1 as rnk from scoreboard s1 left join teams t on s1.team_id = t.team_id left join scoreboard s2 on s1.year=s2.year and s1.week=s2.week and s1.playoffs=s2.playoffs and s1.game_id=s2.game_id and s1.location<>s2.location group by s1.team_id order by tot_wins desc;
Это дает следующие результаты:
team_id division_id tot_wins rnk -------------------------------------- 10 1 44 1 2 1 42 2 3 2 42 2 8 1 39 4 5 2 37 5 . . .
Однако мне приходит в голову, что я уже попадал в этот результирующий набор , и это фактически не решает мою проблему .
Чтобы избежать путаницы, я отдельно разместил проблему «последующих действий» .
Мне нравится ссылка Игнасио на его ответ. Но если вы все еще хотите использовать PHP, вы можете собирать ряды по SCORE и назначать команды для каждого балла. Вероятно, это не самый эффективный способ сделать это, но это сработает.
$ranks = array(); while ($row = mysql_fetch_assoc($result)) { $ranks[$row['pts']][] = $row['team_id']; }
$ranks
будет массивом, который может выглядеть как …
$ranks[89] = array(1); $ranks[87] = array(2); $ranks[76] = array(3,4); $ranks[52] = array(5);
Используйте foreach
на $ranks
и дважды проверяйте, каким образом появятся точки (восходящие или нисходящие). Вы можете использовать count (), чтобы узнать, есть ли связь.
$exists = array(); if ($row['team_id'] == $team_id && !in_array($row['pts'], $exists)) { //current team in resultset matches team in question, set team's rank $exists[] = $row['pts']; $arr_ranks['tp']['cat'] = 'Total Points'; $arr_ranks['tp']['actual'] = number_format($row['pts'],1); $arr_ranks['tp']['league_rank'] = $rnk; $arr_ranks['tp']['div_rank'] = $div_rnk; }
На этот вопрос был дан ответ .
Запрос:
SELECT a.team_id, a.wins, count(*) instances FROM (SELECT s1.team_id, sum(s1.score>s2.score) wins FROM scoreboard s1 LEFT JOIN scoreboard s2 ON s1.year=s2.year AND s1.week=s2.week AND s1.playoffs=s2.playoffs AND s1.game_id=s2.game_id AND s1.location<>s2.location GROUP BY s1.team_id) AS a LEFT JOIN (SELECT sum(s1.score>s2.score) wins FROM scoreboard s1 LEFT JOIN scoreboard s2 ON s1.year=s2.year AND s1.week=s2.week AND s1.playoffs=s2.playoffs AND s1.game_id=s2.game_id AND s1.location<>s2.location GROUP BY s1.team_id) AS b ON a.wins = b.wins GROUP BY a.team_id, b.wins ORDER BY a.wins DESC;
Это дает результат …
================================= |team_id | wins |instances | ================================= |10 | 44 |1 | |2 | 42 |3 | //tie |9 | 42 |3 | //tie |5 | 42 |3 | //tie |3 | 41 |1 | |11 | 40 |1 | |... | | | =================================
Затем, в PHP, я смогу обнаружить все связи, проверив, когда $row['instances'] > 1
.