Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General »

Consulta que no me sale ordenada

Estas en el tema de Consulta que no me sale ordenada en el foro de Bases de Datos General en Foros del Web. Hola, saludo a todos/as... Tengo una table en Access donde tengo tres campos: - Nombres de jugadores de futbol. - Las puntuaciones totales para cada ...
  #1 (permalink)  
Antiguo 07/05/2008, 08:19
Avatar de 3pies
Colaborador
 
Fecha de Ingreso: diciembre-2003
Ubicación: Desde una destilería
Mensajes: 2.584
Antigüedad: 20 años, 5 meses
Puntos: 144
Consulta que no me sale ordenada

Hola, saludo a todos/as...

Tengo una table en Access donde tengo tres campos:

- Nombres de jugadores de futbol.
- Las puntuaciones totales para cada uno de ellos (1000 puntos, 858 puntos, etc…) y que es la suma de todos los puntos que le han dado los usuarios.
- El número de votos dados a cada jugador (número de personas que han votado a fulanito o a menganito).

Bien, ahora imaginad que quiero presentar los jugadores en orden descendente en función de su valoración (el jugador mejor valorado arriba, y el peor valorado al final). Como no tengo un campo en la base de datos que informe de cual es el mejor valorado, tenemos que hacer una operación dividiendo el campo valoracion_total (que es el total de puntos recibidos por cada jugador), entre veces_valorado (veces que se ha votado por ese jugador).

Problema que surge: Hay jugadores que no han recibido ninguna valoración, por lo que cero dividido entre cero, da error. Es decir, una consulta de este tipo, no funciona:

Código:
SELECT * FROM jugadores ORDER BY (valoracion_total/veces_valorado) DESC
Para solucionarlo, se me ha ocurrido seleccionar primero el grupo de jugadores que han sido valorados más de cero veces (1, 2, 3, ...o n veces), es decir, veces_valorado > 0, y después añadir a continuación el grupo de jugadores que no han tenido valoración. Es decir, uniendo estas 2 consultas:
[color=green]
Código:
SELECT * FROM jugadores WHERE veces_valorado>0 ORDER BY (valoracion_total/veces_valorado) DESC, veces_valorado DESC, jugador ASC
Código:
SELECT * FROM jugadores WHERE veces_valorado=0 ORDER BY jugador ASC
La primera de esas dos sentencias ordenaría los jugadores con alguna valoración, primero en función de la división valoracion_total/veces_valorado, es decir, en función del jugador mejor valorado al peor valorado. Luego, si varios jugadores tienen la misma valoración, que lo ordene en función de las veces que ha sido valorado cada jugador (esto es útil por ejemplo, para diferenciar un jugador que tiene 1 solo voto, y a la que le han dado 10 puntos, de otro jugador que tiene 3 votos y a la que le han dado 30 puntos en total, ...en ambos casos, la valoración del jugador es de 10 puntos, pero quiero que presente primero los que más votos han tenido, es decir, ese jugador al que han votado 3 veces). Luego, en caso de empates, mostraría los jugadores por su nombre, en orden alfabético ascendente.

La segunda consulta mostraría los jugadores que no han sido valoradas, por el su nombre, de forma ascendente.

Problemaaaaaaaaaaaa: Si uno ambas sentencias, no me mantiene el orden lógico por el que me debería mostrar los jugadores. Es decir, si utilizo la siguiente consulta, me muestra los jugadores por su nombre de forma ascendente, con independencia de la puntuación recibida por cada jugador:

Código:
(SELECT * FROM jugadores WHERE veces_valorado>0 ORDER BY (valoracion_total/veces_valorado) DESC, veces_valorado DESC, jugador ASC) UNION ALL (SELECT * FROM jugadores WHERE veces_valorado=0 ORDER BY jugador ASC)
A ver si me podéis decir que estoy haciendo mal para que no me muestre la consulta, tal y como yo la he especificado (desconozco si UNION ALL sirve para unir dos grupos de datos de una misma tabla, porque siempre la he visto utilizada para tablas diferentes).

Gracias miles.
  #2 (permalink)  
Antiguo 07/05/2008, 09:09
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 1 mes
Puntos: 574
Re: Consulta que no me sale ordenada

Código:
SELECT * 
    FROM jugadores 
    ORDER BY 
          iif(veces_valorado<>0,valoracion_total/veces_valorado,0) DESC,
              veces_valorado DESC, 
              jugador ASC;
Y esto funciona?

Código:
SELECT jugador,
             iif(veces_valorado<>0,valoracion_total/veces_valorado,0)  as valoracionMedia,
             veces_valorado 
    FROM jugadores 
    ORDER BY 
          iif(veces_valorado<>0,valoracion_total/veces_valorado,0) DESC,
              veces_valorado DESC, 
              jugador ASC;
Casi mejor asi no?
Quim

Última edición por quimfv; 07/05/2008 a las 09:14
  #3 (permalink)  
Antiguo 07/05/2008, 09:11
Avatar de 3pies
Colaborador
 
Fecha de Ingreso: diciembre-2003
Ubicación: Desde una destilería
Mensajes: 2.584
Antigüedad: 20 años, 5 meses
Puntos: 144
Re: Consulta que no me sale ordenada

Sí, así funciona perfectamente, pero ¿por qué no funciona mi "sistema"?.

Muchas gracias por tu respuesta.

PD: Aplicaré tu condicional, pero no entiendo porqué cohone no funciona lo mío.
  #4 (permalink)  
Antiguo 07/05/2008, 09:16
Avatar de Taribo007  
Fecha de Ingreso: agosto-2007
Mensajes: 1.338
Antigüedad: 16 años, 8 meses
Puntos: 18
Re: Consulta que no me sale ordenada

A ver si te vale con esto:

SELECT *
FROM jugadores
ORDER BY IIf(nz([veces_valorado],0)=0,0,[Valoracion_Total]/[veces_valorado]) DESC;

Un saludo
  #5 (permalink)  
Antiguo 07/05/2008, 09:26
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 1 mes
Puntos: 574
Re: Consulta que no me sale ordenada

Supongo que se hace un lio de indices, sql es declarativo a diferencia de los otros lenguajes que podriamos decir que son imperativos...

Es decir en Sql tu dices lo que quieres y el se busca la vida para obtenerlo de la forma mas optima segun el motor de bbdd que lo este ejecutando.

En los otros lenguajes tu programas lo que hay que hacer para obtener lo que quieres.

Si no usaras Access, es decir si usaras un motor de verdad de bbdd tendrias el comando explain plan que muestra como se ejecutara la sentencia, seguramente veriamos que esta ejecutando primero los select y luego aplica los indices con lo que al no ser iguales se hace un lio... pero bueno esto ultimo es una especulación.

nz([veces_valorado],0) lo necesitaras si hay nulos en veces_valorado pero si su valor por defecto es cero no hace falta. Gràcias Taribo007 por la mejora.

Quim

Última edición por quimfv; 07/05/2008 a las 09:39
  #6 (permalink)  
Antiguo 07/05/2008, 09:28
Avatar de 3pies
Colaborador
 
Fecha de Ingreso: diciembre-2003
Ubicación: Desde una destilería
Mensajes: 2.584
Antigüedad: 20 años, 5 meses
Puntos: 144
Re: Consulta que no me sale ordenada

Gracias Taribo007, si a tu consulta le añado un "veces_valorado DESC" entonces sí. Ahora

Pero sigo con mi duda: ¿Por qué no ordena correctamente los datos devueltos, mi consulta con el UNION ALL?.

PD: Por cierto, desconocía el uso de la función nz.
  #7 (permalink)  
Antiguo 07/05/2008, 09:31
Avatar de 3pies
Colaborador
 
Fecha de Ingreso: diciembre-2003
Ubicación: Desde una destilería
Mensajes: 2.584
Antigüedad: 20 años, 5 meses
Puntos: 144
Re: Consulta que no me sale ordenada

Gracias por tu respuesta Quim. ¿Te parece incorrecta la construcción de mi sentencia con el UNION ALL (no me da error, sino que me ordena los datos como le sale del mismísimo)?. ¿Ves algún error por algún lado (yo soy incapaz de verlo)?.

PD: veces_valorado es cero por defecto (gracias por la aclaración sobre la función nz).

Última edición por 3pies; 07/05/2008 a las 09:42
  #8 (permalink)  
Antiguo 07/05/2008, 09:55
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 1 mes
Puntos: 574
Re: Consulta que no me sale ordenada

El problema creo que no esta en la sentencia sino en como la ejecuta el motor como te he dicho. Sabes que en Sql se puede pedir lo mismo de formas distintas, pues he visto dos sentencias correctas el resultado de las quales deberia ser el mismo y una se queda colgada y la otra se ejecuta en nanosegundos...

No tengo ningun ejemplo de union all con sentencias order para cada select, en todo caso el error tendria que venir por aqui.

Una forma de ver si estan bien es ejecutarlas por separado, si funcionan y como tendran los mimos campos en principio deberian poderse unir. Siempre y cuando el proceso de ejecucion sea el seguiente:

Select
Order
Select
Order
Union

Pero si por lo que sea, las limitaciones del motor por ejemplo el proceso es

Select
Select
Union
Order
Order

esto funcionaria si el Order fuera igual para los dos selects pero al no serlo vete a saber que hace...

Otra es mirar que dice la teoria sobre el UNION ALL y los ORDER BY pero que yo recuerde solo dice que las dos querys a unir deben tener los mismos campos....


Quim

Última edición por quimfv; 07/05/2008 a las 10:05
  #9 (permalink)  
Antiguo 07/05/2008, 10:00
Avatar de 3pies
Colaborador
 
Fecha de Ingreso: diciembre-2003
Ubicación: Desde una destilería
Mensajes: 2.584
Antigüedad: 20 años, 5 meses
Puntos: 144
Re: Consulta que no me sale ordenada

Gracias por la respuesta.

Por cierto pensaba que evaluando ese condicional (si el jugador no tiene valoración => 0), iba a hacer que la consulta fuera algo lenta, pero con asombro veo que es rapidísima.

PD1: Gracias por la última aclaración.

PD2: No llevo suelto , pero sí que os doy karma a los 2, por vuestra ayuda.

Última edición por 3pies; 07/05/2008 a las 10:09
  #10 (permalink)  
Antiguo 07/05/2008, 11:47
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 1 mes
Puntos: 574
Re: Consulta que no me sale ordenada

De la ayuda de MySql.

Quim


Cita:
To apply ORDER BY or LIMIT to an individual SELECT, place the clause inside the parentheses that enclose the SELECT:

(SELECT a FROM t1 WHERE a=10 AND B=1 ORDER BY a LIMIT 10)
UNION
(SELECT a FROM t2 WHERE a=11 AND B=2 ORDER BY a LIMIT 10);
Use of ORDER BY for individual SELECT statements implies nothing about the order in which the rows appear in the final result because UNION by default produces an unordered set of rows. If ORDER BY appears with LIMIT, it is used to determine the subset of the selected rows to retrieve for the SELECT, but does not necessarily affect the order of those rows in the final UNION result. If ORDER BY appears without LIMIT in a SELECT, it is optimized away because it will have no effect anyway.

To cause rows in a UNION result to consist of the sets of rows retrieved by each SELECT one after the other, select an additional column in each SELECT to use as a sort column and add an ORDER BY following the last SELECT:

(SELECT 1 AS sort_col, col1a, col1b, ... FROM t1)
UNION
(SELECT 2, col2a, col2b, ... FROM t2) ORDER BY sort_col;
To additionally maintain sort order within individual SELECT results, add a secondary column to the ORDER BY clause:

(SELECT 1 AS sort_col, col1a, col1b, ... FROM t1)
UNION
(SELECT 2, col2a, col2b, ... FROM t2) ORDER BY sort_col, col1a;
  #11 (permalink)  
Antiguo 07/05/2008, 12:33
Avatar de 3pies
Colaborador
 
Fecha de Ingreso: diciembre-2003
Ubicación: Desde una destilería
Mensajes: 2.584
Antigüedad: 20 años, 5 meses
Puntos: 144
Re: Consulta que no me sale ordenada

Jajajajajaa, más claro el agua.

Muchas gracias
  #12 (permalink)  
Antiguo 08/05/2008, 03:25
 
Fecha de Ingreso: febrero-2007
Mensajes: 1.292
Antigüedad: 17 años, 3 meses
Puntos: 13
Re: Consulta que no me sale ordenada

Cita:
Iniciado por quimfv Ver Mensaje
Supongo que se hace un lio de indices, sql es declarativo a diferencia de los otros lenguajes que podriamos decir que son imperativos...
Solo un pequeño apunte, SQL es un lenguaje declarativo algebraico

Un saludo
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 21:46.