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

Ayuda con INNER JOIN y SUM

Estas en el tema de Ayuda con INNER JOIN y SUM en el foro de Mysql en Foros del Web. Me estoy rompiendo la cabeza con este query que es para obtener una lista de los usuarios con más puntos siempre y cuando los usuarios ...
  #1 (permalink)  
Antiguo 09/09/2009, 23:47
 
Fecha de Ingreso: febrero-2007
Mensajes: 309
Antigüedad: 17 años, 2 meses
Puntos: 16
Ayuda con INNER JOIN y SUM

Me estoy rompiendo la cabeza con este query que es para obtener una lista de los usuarios con más puntos siempre y cuando los usuarios tengan al menos una foto en la tabla fotos.

La tabla puntaje tiene los puntos que recibio el usuario cada dia, por eso hago SUM() para sumar todo el periodo.
El problema es que depende la cantidad de fotos que tenga el usuario (JOIN con tabla fotos) se multiplica el valor de SUM(). No entiendo porque hace eso si estoy usando GROUP BY usuario!

Este es el query:
Código:
SELECT 
    puntaje.usuario, 
    sum(puntaje.puntos) as totalPuntos,
    usuarios.id as usuarioId
FROM
    puntaje
    INNER JOIN usuarios ON puntaje.usuario=usuarios.usuario
    INNER JOIN fotos ON fotos.usuarioId=usuarios.id /*porque debe tener al menos una foto*/

WHERE 
    usuarios.activo=1 AND 
    puntaje.fecha >= DATE_SUB(curdate(), INTERVAL 1 MONTH)

GROUP BY puntaje.usuario
ORDER BY totalPuntos DESC 
LIMIT 10
¿Que estoy haciendo mal?

Gracias por adelantado!
__________________
Responder encuestas
  #2 (permalink)  
Antiguo 10/09/2009, 02:29
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 1 mes
Puntos: 574
Respuesta: Ayuda con INNER JOIN y SUM

Lo hace por que primero hace el join y despues el SUM group by

Es decir si tenemos


Puntage
usuario:::puntos ....
1::::::::::::::1
1::::::::::::::2
2::::::::::::::5

Usuarios
id:::::Nombre...
1::::::Pepito
2::::::Pepita

Fotos
idfoto:::::usuarioId....
1::::::::::::::1
2::::::::::::::1
3::::::::::::::1
4::::::::::::::2

Puntage INNER JOIN Usuarios

usuario:::puntos:::id:::::Nombre...
1::::::::::::::1::::::::::1::::::Pepito
1::::::::::::::2::::::::::1::::::Pepito
2::::::::::::::5::::::::::2::::::Pepita

(Lo anterior)INNER JOIN Fotos

usuario:::puntos:::id:::::Nombre:::::idfoto:::::us uarioId....
1::::::::::::::1::::::::::1::::::Pepito::::::::1:: :::::::::1
1::::::::::::::1::::::::::1::::::Pepito::::::::2:: :::::::::1
1::::::::::::::1::::::::::1::::::Pepito::::::::3:: :::::::::1
1::::::::::::::2::::::::::1::::::Pepito::::::::1:: :::::::::1
1::::::::::::::2::::::::::1::::::Pepito::::::::2:: :::::::::1
1::::::::::::::2::::::::::1::::::Pepito::::::::3:: :::::::::1
2::::::::::::::5::::::::::2::::::Pepita::::::::4:: :::::::::2

si sumas por usuarios tendrás

id:::::Nombre:::Sum(Puntos)
1::::::Pepito:::::::::::::9
2::::::Pepita:::::::::::::5

Mira si esto te funciona, y analiza que hace....

Código sql:
Ver original
  1. SELECT
  2.     puntaje.usuario,
  3.     SUM(puntaje.puntos) AS totalPuntos,
  4.     usuarios.id AS usuarioId
  5. FROM
  6.     puntaje
  7.     INNER JOIN usuarios ON puntaje.usuario=usuarios.usuario
  8. WHERE
  9.     usuarios.activo=1 AND
  10.     puntaje.fecha >= DATE_SUB(curdate(), INTERVAL 1 MONTH)
  11. HAVING
  12.     usuarios.id IN (SELECT DISTINCT usuarioId FROM fotos)
  13.     /*porque debe tener al menos una foto*/
  14. GROUP BY puntaje.usuario
  15. ORDER BY totalPuntos DESC
  16. LIMIT 10


Pregunta
Si alguien NO tiene fotos puede tener puntos?....

Si fuera que NO luego cambiando de INNER JOIN a LEFT JOIN entre puntaje y usuarios no tendrias que complicarte la vida con la tabla Fotos... puesto que solo saldran los que esten en puntage, es decir los que tienen puntos, es decir los que tienen alguna foto.... ya que si no tienen fotos no tienen puntos....????!!!

Quim

Última edición por quimfv; 10/09/2009 a las 02:39
  #3 (permalink)  
Antiguo 10/09/2009, 09:12
 
Fecha de Ingreso: febrero-2007
Mensajes: 309
Antigüedad: 17 años, 2 meses
Puntos: 16
De acuerdo Respuesta: Ayuda con INNER JOIN y SUM

Excelente!!! Gracias por tu dedicación al responder el mensaje! Aprendi dos cosas que no sabia.

El SQL que me pasaste estaba bien excepto que HAVING va despues del GROUP BY. O sea quedaría asi:

Código:
SELECT 
    puntaje.usuario, 
    sum(puntaje.puntos) AS totalPuntos,
    usuarios.id AS usuarioId
FROM
    puntaje
    INNER JOIN usuarios ON puntaje.usuario=usuarios.usuario
WHERE 
    usuarios.activo=1 AND 
    puntaje.fecha >= DATE_SUB(curdate(), INTERVAL 1 MONTH)
GROUP BY puntaje.usuario
HAVING 
    usuarios.id IN (SELECT DISTINCT usuarioId FROM fotos)
    /*porque debe tener al menos una foto*/
ORDER BY totalPuntos DESC 
LIMIT 10
Gracias nuevamente!!!
Saludos.
__________________
Responder encuestas
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 17:18.