Ranking con todos los registros

Iniciado por KISKE, 8 Mayo 2013, 20:02 PM

0 Miembros y 1 Visitante están viendo este tema.

KISKE

Hola, quiero hacer algo, pero la única manera que se me ocurre es la más mala de todas.

Código (sql) [Seleccionar]
SELECT nombre FROM datos ORDER BY valor DESC;

Lo que quiero realizar, es que cuando un usuario de la web pide saber su posición en el ranking, le devuelva la posición en la que está, sin tener que pasar por todos los registros, hacer un contador y verificar si el id coincide con el del usuario.

Quisiera saber si hay otra manera, porque debo decir que si esta es la única manera, me siento decepcionado.

Porque tengo aproximadamente 20 mil registros, no puedo hacer un bucle que se repita 20 mil veces cada vez que alguien hace el pedido.


Saludos y gracias de antemano!

MCKSys Argentina

Suponiendo que el campo con el id del user es user_id, y que realizas la consulta para el usuario con id 989898, podrias hacer algo asi:

Código (sql) [Seleccionar]
SELECT nombre FROM datos where user_id = 989898 ORDER BY valor DESC;

Es lo que quieres hacer?
MCKSys Argentina

"Si piensas que algo está bien sólo porque todo el mundo lo cree, no estás pensando."


#!drvy

@MCKSys, pero si el user_id es único... devolverá su nombre si o si sin tomar en cuenta el orden del valor.. o no ? En todo caso tendria que selecionar (SELECT) el valor y filtrar (where) la lista con el user_id.. vamos creo yo.. si me equivoco corrijan me xD

Saludos

MCKSys Argentina

Si el id es unico, entonces el ranking se actualiza siempre, con lo que bastaria hacer algo como:

Código (sql) [Seleccionar]
SELECT nombre, ranking FROM datos WHERE user_id = 989898;

Ahora, si cada vez que cambia el ranking del usuario, se agrega un registro mas, entonces cambia la cosa. Si suponemos que el ranking solo puede aumentar, podria hacerse:

Código (sql) [Seleccionar]
SELECT MAX(ranking) FROM datos WHERE user_id = 989898;

@drvy | BSM: Tienes razón, no incluí el ranking en el SELECT.  :P
MCKSys Argentina

"Si piensas que algo está bien sólo porque todo el mundo lo cree, no estás pensando."


KISKE

Está bien lo que decís, te entiendo, pero no es lo que estoy buscando.
Te doy un ejemplo chiquito.

Supongamos que tengo tres registros.

id | nombre | valor
1  | AKA      | 500
2  | LOL      | 400
3  | AST      | 600


Cuando yo ejecuto la query que todavía no sé como es, quiero que me devuelva lo siguiente:

id | nombre | campo_nuevo (campo creado por la query)
3  | AST      | 1
1  | LOL      | 2
2  | AKA      | 3


Entonces yo lo que hago es simplemente un SELECT del campo_nuevo WHERE id = al usuario que realizó el pedido.


Si se sigue sin entender avisen que intento dar otro ejemplo.

#!drvy

Sigo sin entender xD AKA tiene mas puntuación que LOL.. porque va 2 ? xD No pillo lo que intentas hacer.. xD


Saludos

MCKSys Argentina

También me perdí con la última explicación...  :P
MCKSys Argentina

"Si piensas que algo está bien sólo porque todo el mundo lo cree, no estás pensando."


s00rk

Ok creo entender, lo que el desea es obtener la posicion de algun dato Ejemplo

Usuario calificacion
victor      8
manuel    10
jose        5
manuela   10

Ok ahora lo que el quiere saber es ordenarlos de mayor a menor y al mismo tiempo obtenga la posicion del que busca, que lo podria hacer asi:

$usuario = "victor";
$i = 1;
$sql = mysql_query("SELECT Usuario FROM TABLA Order By calificacion DESC");
for($r = mysql_fetch_object($sql))
{
    if($r->Usuario === $usuario)
    {
        echo "Nombre: ".$r->Usuario." Posicion: ".$i;
    }
    $i++;
}


Eso es lo que el quiere hacer pero sin hacer ese for sino que con una consulta lo haga, porque si son muchos datos y el que buca tiene una posicion MUY alejada tardaria bastante tiempo.


----------------------


Bueno ahora lo que yo opinaria seria que a esa tabla le agregaras una columna llamada ranking de tipo int y ya luego cada cierto tiempo ejecutar esto:

SET @r=0;
UPDATE datos SET Ranking= @r:= (@r+1) ORDER BY valor DESC;

Y ya pues en la consulta solo harias un select como

SELECT usuario, ranking FROM TABLA WHERE Usuario = 'NOMBRE'

Y ya eso podrias hacerlo, es lo que a mi se me ocurre si no deseas hacer el for y tal.

MCKSys Argentina

Si es como dice s00rk, podria ser:

Código (sql) [Seleccionar]
SELECT nombre, valor, (SELECT COUNT(*) FROM Datos ORDER BY valor DESC) rank FROM Datos ORDER BY rank

Aunque no tengo acá para probar...  :P

Saludos!
MCKSys Argentina

"Si piensas que algo está bien sólo porque todo el mundo lo cree, no estás pensando."


KISKE

#9
Cita de: MCKSys Argentina en  9 Mayo 2013, 02:03 AM
Si es como dice s00rk, podria ser:

Código (sql) [Seleccionar]
SELECT nombre, valor, (SELECT COUNT(*) FROM Datos ORDER BY valor DESC) rank FROM Datos ORDER BY rank

Aunque no tengo acá para probar...  :P

Saludos!
El problema es que no tengo un campo que reemplace a rank.



Lo que dijo s00rk es exactamente lo que quiero.
La segunda parte funciona bárbaro creo, el UPDATE ese lo hago aproximadamente cada 10 minutos y debería funcionar joya.

Muchísimas gracias a todos!