Detecta valores duplicados futuros mientras se itera a través de los resultados de MySQL en PHP

Estoy tratando de calcular la clasificación de un equipo en un conjunto ordenado de resultados de MySQL, y el problema que estoy teniendo es la detección de vínculos para que el primer equipo aparezca con el valor vinculado.

Por ejemplo, digamos que el conjunto de resultados es el siguiente:

team_id pts --------------- 1 89 2 87 3 76 4 76 5 52 

Calculo el ranking del equipo con el siguiente 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'] = "" . get_team_name($row['team_id']) . ' (' . number_format($row['pts'],1) . ')'; } $prev_val = $row['pts']; //set current score as previous score for next iteration of loop } 

La lógica de “empate” anterior capturará al equipo # 4 como habiendo empatado con el equipo # 3, pero no al revés .

En otras palabras, para el equipo # 3, $rnk = 3 , mientras que para el equipo # 4, $rnk = T-3 . (Ambos deben ser “T-3”.)

Entonces, la pregunta es: ¿cómo “miro hacia adelante” mientras recorro los resultados para saber si el puntaje actual es un empate / duplicado de puntajes más abajo en la lista, así que puedo tratarlo como un empate junto con los engaños subsiguientes?

Gracias.


EDITAR: Puedo implementar el código de Ignacio si primero almaceno los resultados en una tabla, como "wins" continuación:

 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.locations2.location group by s1.team_id order by tot_wins desc; 

Esto da los siguientes resultados:

 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 . . . 

Sin embargo, se me ocurre que ya estaba llegando a este conjunto de resultados , y esto en realidad no resuelve mi problema .

Para evitar confusiones, he publicado el problema de “seguimiento” por separado .

Me gusta el enlace de Ignacio a su respuesta. Pero si aún desea utilizar PHP, puede recostackr los rangos por SCORE y asignar equipos a cada puntaje. Probablemente no sea la forma más eficiente de hacerlo, pero funcionaría.

 $ranks = array(); while ($row = mysql_fetch_assoc($result)) { $ranks[$row['pts']][] = $row['team_id']; } 

$ranks sería una matriz que podría parecerse a …

 $ranks[89] = array(1); $ranks[87] = array(2); $ranks[76] = array(3,4); $ranks[52] = array(5); 

Use un foreach en $ranks , y verifique de qué manera saldrán los puntos (ascendente o descendente). Puedes usar count () para ver si hay un empate.

 $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; } 

Esta pregunta ha sido respondida aquí .

La consulta:

 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; 

Esto da la salida …

 ================================= |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 | |... | | | ================================= 

Luego, en PHP, podré detectar todos los vínculos comprobando cuando $row['instances'] > 1 .