Foro de elhacker.net

Programación => Bases de Datos => Mensaje iniciado por: KISKE en 8 Mayo 2013, 20:02 pm



Título: Ranking con todos los registros
Publicado por: KISKE en 8 Mayo 2013, 20:02 pm
Hola, quiero hacer algo, pero la única manera que se me ocurre es la más mala de todas.

Código
  1. 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!


Título: Re: Ranking con todos los registros
Publicado por: MCKSys Argentina en 8 Mayo 2013, 20:38 pm
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
  1. SELECT nombre FROM datos WHERE user_id = 989898 ORDER BY valor DESC;

Es lo que quieres hacer?


Título: Re: Ranking con todos los registros
Publicado por: #!drvy en 8 Mayo 2013, 20:49 pm
@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


Título: Re: Ranking con todos los registros
Publicado por: MCKSys Argentina en 8 Mayo 2013, 21:14 pm
Si el id es unico, entonces el ranking se actualiza siempre, con lo que bastaria hacer algo como:

Código
  1. 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
  1. SELECT MAX(ranking) FROM datos WHERE user_id = 989898;

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


Título: Re: Ranking con todos los registros
Publicado por: KISKE en 9 Mayo 2013, 00:05 am
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.


Título: Re: Ranking con todos los registros
Publicado por: #!drvy en 9 Mayo 2013, 00:27 am
Sigo sin entender xD AKA tiene mas puntuación que LOL.. porque va 2 ? xD No pillo lo que intentas hacer.. xD


Saludos


Título: Re: Ranking con todos los registros
Publicado por: MCKSys Argentina en 9 Mayo 2013, 00:46 am
También me perdí con la última explicación...  :P


Título: Re: Ranking con todos los registros
Publicado por: s00rk en 9 Mayo 2013, 01:35 am
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.


Título: Re: Ranking con todos los registros
Publicado por: MCKSys Argentina en 9 Mayo 2013, 02:03 am
Si es como dice s00rk, podria ser:

Código
  1. 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!


Título: Re: Ranking con todos los registros
Publicado por: KISKE en 10 Mayo 2013, 02:23 am
Si es como dice s00rk, podria ser:

Código
  1. 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!