Ver Mensaje Individual
  #4 (permalink)  
Antiguo 24/12/2008, 05:21
jurena
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años, 1 mes
Puntos: 300
Respuesta: Ayuda con consulta

Cita:
1. ¿Que es lo que hace HAVING SUM?, esto lo desconozco.
2. ¿Hacia falta un INNER JOIN ? ¿Se puede con movimiento.id_usuario = usuario.id_usuario simplemente?.


SELECT usuario.id_usuario, usuario.nombre, movimiento.id_actividad, SUM( movimiento.horas_empleadas ) AS TOTAL_HORAS, movimiento.id_usuario
FROM usuario
INNER JOIN movimiento ON movimiento.id_usuario = usuario.id_usuario
GROUP BY movimiento.id_usuario
HAVING SUM( movimiento.horas_empleadas ) <8
LIMIT 0 , 30

Trataré de responderte en el orden inverso.
2) Puede usarse también movimiento.id_usuario = usuario.id_usuario, y el resultado es el mismo; pero, en mi opinión, es más eficiente y deja el código más claro INNER JOIN ... ON... He leído decir a quienes de esto saben, que, si los índices están bien hechos, la consulta se optimiza con INNER JOIN. También he leído a otros que también saben sobre el tema decir que el parseador corrige y el resultado es el mismo en ambos casos. Yo, aunque no fuera cierto lo primero (creo que sí lo es, aunque no soy técnico), sólo por la claridad del código, prefiero usar INNER JOIN... ON... en estos casos. Creo que es un buen hábito para construir la sintaxis SQL.

1) HAVING se usa tras GROUP BY y te permite consultar (restringir, condicionar) datos resultantes de la agrupación. Por eso se escribe detrás. Si tú buscaras un dato existente en la tabla o que pudiera deducirse a partir de los datos de los registros (uno a uno), usarías el WHERE y lo pondrías antes del GROUP BY... Pero lo que tú buscas es algo que resulta de agrupar y por tanto debes emplear el HAVING... El SUM(...) es la función aritmética agrupada sobre la que buscas el resultado.
Tú te traes los nombres y los movimientos; con el where podrías encontrar los movimientos cuya cantidad fuera, por ej., superior a 1000, pero no la suma de movimientos cuya cantidad fuera superior a 1000, pues eso sólo puedes hacerlo después de agrupar los resultados de la consulta por algún criterio (en este caso el id del usuario) y sumar, y no antes...
Naturalmente, es posible y frecuente hacer consultas con WHERE antes del GROUP BY y con HAVING detrás. Con el where buscas un dato que no es fruto de la agrupación, y con having el que es resultado de la misma (ej.el usuario cuya suma de operaciones sólo superiores a 1000 sea una cantidad superior a 100000: SELECT usuario, SUM(operacion) tot FROM tabla WHERE operacion > 1000 GROUP BY idusuario HAVING tot > 100000). En cuanto al uso de SUM (...) tras el HAVING en lugar del alias TOTAL_HORAS, como puedes ver en este ejemplo.

SELECT usuario.id_usuario, usuario.nombre, movimiento.id_actividad, SUM( movimiento.horas_empleadas ) AS TOTAL_HORAS, movimiento.id_usuario
FROM usuario
INNER JOIN movimiento ON movimiento.id_usuario = usuario.id_usuario
GROUP BY movimiento.id_usuario
HAVING TOTAL_HORAS < 8
LIMIT 0 , 30[/QUOTE]

es más bien una precaución. No siempre los alias funcionan, y si además cambias de MySQL a otro motor puedes encontrarte con algún problema. Pero prueba si quieres utilizando el alias como te he puesto en el ejemplo anterior.

Última edición por jurena; 24/12/2008 a las 08:13