Ver Mensaje Individual
  #5 (permalink)  
Antiguo 29/03/2009, 15:53
Avatar de gnzsoloyo
gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: bucle con mysql?

En esencia el problema es simple. El tema se resuelve exactamente como lo planteas, pero en el area de SQL la lógica graficada se representa exactamente al reves: La selección "gruesa" es la interna y los datos buscados están en el exterior.
Me explico:
Se trata de una consulta a tres niveles, lo que vulgarmente se denomina "consulta anidadas" y se hace realizando las etapas de a una desde la más gruesa a la mas fina (interior-> exterior).
Lo importante es lo siguiente: Cada consulta crea una tabla virtual en memoria, por lo que para que un dato que se usa en la externa exista, debe ser derivado a ella desde la interna. Esto significa que el campo "referido" debe ser parte de la consulta más gruesa, aunque en esa consulta no signifique nada.
Esto sería:
Código sql:
Ver original
  1. SELECT usuario_id, referido, COUNT(*)  compras
  2. FROM usuario LEFT JOIN compra USING(usuario_id)
  3. GROUP BY usuario_id;

Sabemos que esto genera una sumatoria de las compras realizadas por cada usuario. Si lo que deseamos es la suma total de compras por referidos, pero con subtotales, debemos hacer una subconsulta:
Código sql:
Ver original
  1. SELECT referido, usuario_id, nombres, apellidos,  SUM(compras) TotalCompras
  2. FROM
  3.     (SELECT usuario_id, referido,nombres, apellidos,  COUNT(*)  compras
  4.     FROM usuario LEFT JOIN compra USING(usuario_id)
  5.     GROUP BY usuario_id) t1
  6. GROUP BY referido WITH ROLLUP;

Esto debe devolver la suma parcial de cada uno, además de una línea con el total. Si le quitas el WITH ROLLUP, solamente te devolverá el valor de la suma total, pero para eso tines otra consulta, que hace todo:
Código sql:
Ver original
  1. SELECT usuario_id, referido, COUNT(*)  compras
  2. FROM usuario LEFT JOIN compra USING(usuario_id)
  3. GROUP BY referido;

Nota que con sólo cambiar el campo de agrupamiento tienes la suma que necesitas... sin más trámite.

Si cambias LEFT JOIN por INNER JOIN, te devolverá solamente los usuarios que hayan sido referidos por alguien. COmo por ejemplo, todos los referidos a "juan", pero no las compras hechas por "juan", si juan no tiene un referido.

Aquí lo único que debes establecer es el nivel de desagregación que necesitas obtener.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)