Ver Mensaje Individual
  #2 (permalink)  
Antiguo 27/11/2014, 15:52
leonardo_josue
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 4 meses
Puntos: 447
Respuesta: Join 4 tablas

Hola alpe2000:

En realidad no estás tan alejado de la respuesta, sin embargo tienes algunos detalles a considerar:

1. en las cláusulas ON, es recomendable que sólo utilices aquellas condiciones que involucran a las llaves de las tablas, las condiciones para filtrar la información debes colocarlas en la sección WHERE.
2. Tienes un problema con las subconsultas, ya que NO ESTÁS AGRUPANDO POR PRODUCTO, por lo tanto, tanto el promedio como el conteo están arrojando un resultado general, no particular para un producto.

No es lo mismo poner esto:

Código MySQL:
Ver original
  1. SELECT id_producto opi_id_producto, activo opi_act, COUNT(*) total_opiniones
  2. FROM opiniones

a poner esto:

Código MySQL:
Ver original
  1. SELECT id_producto opi_id_producto, activo opi_act, COUNT(*) total_opiniones
  2. FROM opiniones
  3. GROUP BY id_producto opi_id_producto, activo opi_act

3. Evita el uso de SELECT *, esto tiene un pésimo rendimiento... aun cuando necesites TODOS los campos de una tabla (que es un caso poco común), es mejor que listes todos y cada uno de los campos.

El resto parece estar en orden, pero veamos si te queda más claro con este ejemplo.

Supongamos que tienes las siguientes tablas:

Código MySQL:
Ver original
  1. mysql> SELECT * FROM productos;
  2. +-------------+-----------------+
  3. | id_producto | descripcion     |
  4. +-------------+-----------------+
  5. |           1 | producto uno    |
  6. |           2 | producto dos    |
  7. |           3 | producto tres   |
  8. |           4 | producto cuatro |
  9. +-------------+-----------------+
  10. 4 rows in set (0.00 sec)
  11.  
  12.  
  13. mysql> SELECT * FROM votos;
  14. +---------+-------------+------+
  15. | id_voto | id_producto | voto |
  16. +---------+-------------+------+
  17. |       1 |           1 |   10 |
  18. |       2 |           1 |    9 |
  19. |       3 |           1 |   10 |
  20. |       4 |           2 |    7 |
  21. |       5 |           2 |    9 |
  22. +---------+-------------+------+
  23. 5 rows in set (0.00 sec)
  24.  
  25. mysql> SELECT * FROM comentarios;
  26. +---------------+-------------+----------------+
  27. | id_comentario | id_producto | comentario     |
  28. +---------------+-------------+----------------+
  29. |             1 |           1 | comentario 1.1 |
  30. |             2 |           1 | comentario 1.2 |
  31. |             3 |           3 | comentario 3.1 |
  32. +---------------+-------------+----------------+
  33. 3 rows in set (0.00 sec)

es decir, tienes cuatro productos:
  • el producto UNO tiene comentarios y votos
  • el producto DOS solo tiene votos, pero no tiene comentarios
  • el producto TRES solo tiene comentarios, pero no tiene votos
  • el producto CUATRO no tiene ni comentarios ni votos

Ahora, para obtener el PROMEDIO de votos y el CONTEO de comentarios, tienes que hacer uso de las funciones de agrupación PERO UTILIZAR EL GROUP BY:

Código MySQL:
Ver original
  1. mysql> SELECT id_producto, AVG(voto) promedio_votos
  2.     -> FROM votos
  3.     -> GROUP BY id_producto;
  4. +-------------+----------------+
  5. | id_producto | promedio_votos |
  6. +-------------+----------------+
  7. |           1 |         9.6667 |
  8. |           2 |         8.0000 |
  9. +-------------+----------------+
  10. 2 rows in set (0.00 sec)
  11.  
  12. mysql> SELECT id_producto, COUNT(id_producto) total_comentarios
  13.     -> FROM comentarios
  14.     -> GROUP BY id_producto;
  15. +-------------+-------------------+
  16. | id_producto | total_comentarios |
  17. +-------------+-------------------+
  18. |           1 |                 2 |
  19. |           3 |                 1 |
  20. +-------------+-------------------+
  21. 2 rows in set (0.00 sec)

Entonces si, puedes hacer los LEFT JOIN'S para asociar estas cantidades a sus productos:

Código MySQL:
Ver original
  1. mysql> SELECT p.id_producto, p.descripcion, v.promedio_votos, c.total_comentarios
  2.     -> FROM productos p
  3.     -> LEFT JOIN ( SELECT id_producto, AVG(voto) promedio_votos
  4.     ->             FROM votos
  5.     ->             GROUP BY id_producto) v ON v.id_producto = p.id_producto
  6.     -> LEFT JOIN ( SELECT id_producto, COUNT(id_producto) total_comentarios
  7.     ->             FROM comentarios
  8.     ->             GROUP BY id_producto) c ON c.id_producto = p.id_producto;
  9. +-------------+-----------------+----------------+-------------------+
  10. | id_producto | descripcion     | promedio_votos | total_comentarios |
  11. +-------------+-----------------+----------------+-------------------+
  12. |           1 | producto uno    |         9.6667 |                 2 |
  13. |           3 | producto tres   |           NULL |                 1 |
  14. |           2 | producto dos    |         8.0000 |              NULL |
  15. |           4 | producto cuatro |           NULL |              NULL |
  16. +-------------+-----------------+----------------+-------------------+
  17. 4 rows in set (0.00 sec)

Haz los ajustes que te comento y si continuas con problemas, postea algunos datos de ejemplo de tus tablas y dinos en qué está fallando tu consulta.

Saludos
Leo