Ver Mensaje Individual
  #3 (permalink)  
Antiguo 12/05/2014, 21:43
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: query para activos y pendientes

Hola Silver:

El problema que tienes es bastante común, y se debe al hecho de que tienes dos combinaciones 1 a n, pero al unirlas se convierten en una relación n a m, trataré de explicarme con un ejemplo:

Supongamos que tienes estos datos:

Código MySQL:
Ver original
  1. mysql> SELECT * FROM tabla1;
  2. +------+-------------+
  3. | id   | descripcion |
  4. +------+-------------+
  5. |    1 | uno         |
  6. |    2 | dos         |
  7. |    3 | tres        |
  8. +------+-------------+
  9. 3 rows in set (0.00 sec)
  10.  
  11. mysql> SELECT * FROM tabla2;
  12. +------+-------------+
  13. | id   | descripcion |
  14. +------+-------------+
  15. |    1 | uno         |
  16. |    2 | dos         |
  17. |    4 | cuatro      |
  18. +------+-------------+
  19. 3 rows in set (0.00 sec)
  20.  
  21. mysql> SELECT * FROM tabla3;
  22. +------+-------------+
  23. | id   | descripcion |
  24. +------+-------------+
  25. |    1 | uno         |
  26. |    1 | uno         |
  27. |    1 | uno         |
  28. |    2 | dos         |
  29. +------+-------------+
  30. 4 rows in set (0.00 sec)

Supongamos que quieres saber cuantas veces aparecen los registros de la tabla1 en las tablas dos y tres, haciéndolo por separado, no hay ningún problema:

Código MySQL:
Ver original
  1. mysql> SELECT t1.id, t1.descripcion, COUNT(t2.id) total_t2
  2.     -> FROM tabla1 T1
  3.     -> LEFT JOIN tabla2 T2 ON T1.id = T2.id
  4.     -> GROUP BY T1.id, T1.descripcion;
  5. +------+-------------+----------+
  6. | id   | descripcion | total_t2 |
  7. +------+-------------+----------+
  8. |    1 | uno         |        1 |
  9. |    2 | dos         |        1 |
  10. |    3 | tres        |        0 |
  11. +------+-------------+----------+
  12. 3 rows in set (0.00 sec)
  13.  
  14. mysql> SELECT t1.id, t1.descripcion, COUNT(t3.id) total_t3
  15.     -> FROM tabla1 T1
  16.     -> LEFT JOIN tabla3 T3 ON T1.id = T3.id
  17.     -> GROUP BY T1.id, T1.descripcion;
  18. +------+-------------+----------+
  19. | id   | descripcion | total_t3 |
  20. +------+-------------+----------+
  21. |    1 | uno         |        3 |
  22. |    2 | dos         |        1 |
  23. |    3 | tres        |        0 |
  24. +------+-------------+----------+
  25. 3 rows in set (0.00 sec)

Sin embargo, ¿Qué pasa cuando unes los dos COUNT's?

Código MySQL:
Ver original
  1. mysql> SELECT t1.id, t1.descripcion, COUNT(t2.id) total_t2, COUNT(t3.id) total_t3
  2.     -> FROM tabla1 T1
  3.     -> LEFT JOIN tabla2 T2 ON T1.id = T2.id
  4.     -> LEFT JOIN tabla3 T3 ON T1.id = T3.id
  5.     -> GROUP BY T1.id, T1.descripcion;
  6. +------+-------------+----------+----------+
  7. | id   | descripcion | total_t2 | total_t3 |
  8. +------+-------------+----------+----------+
  9. |    1 | uno         |        3 |        3 |
  10. |    2 | dos         |        1 |        1 |
  11. |    3 | tres        |        0 |        0 |
  12. +------+-------------+----------+----------+
  13. 3 rows in set (0.00 sec)

Aquí las cuentas ya no cuadran. Para entender bien el problema observa qué pasa cuando no agrupas, es decir, colocas simplemente los LEFT JOIN's:

Código:
mysql> SELECT *
    -> FROM tabla1 T1
    -> LEFT JOIN tabla2 T2 ON T1.id = T2.id
    -> LEFT JOIN tabla3 T3 ON T1.id = T3.id;
+------+-------------+------+-------------+------+-------------+
| id   | descripcion | id   | descripcion | id   | descripcion |
+------+-------------+------+-------------+------+-------------+
|    1 | uno         |    1 | uno         |    1 | uno         |
|    1 | uno         |    1 | uno         |    1 | uno         |
|    1 | uno         |    1 | uno         |    1 | uno         |
|    2 | dos         |    2 | dos         |    2 | dos         |
|    3 | tres        | NULL | NULL        | NULL | NULL        |
+------+-------------+------+-------------+------+-------------+
5 rows in set (0.00 sec)
La relación entres tus tablas 1 y dos es 1 a n, igual que la relación entre las tablas 1 y 3, sin embargo, al ponerlas juntas, entonces creas una relación entre 2 y 3 n a m... ¿qué tienes que hacer?, agrupar primeramente las tablas 2 y tres de tal manera que sólo tengas 1 registro por cada id, entonces la relación pasa a ser una relación 1 a 1 entre las tablas... es decir, algo como esto:

Código MySQL:
Ver original
  1. mysql> SELECT t1.id, t1.descripcion, total_t2, total_t3
  2.     -> FROM tabla1 T1
  3.     -> LEFT JOIN ( SELECT id, descripcion, COUNT(*) total_t2
  4.     ->      FROM tabla2
  5.     ->      GROUP BY id, descripcion) T2 ON T1.id = T2.id
  6.     -> LEFT JOIN ( SELECT id, descripcion, COUNT(*) total_t3
  7.     ->      FROM tabla3
  8.     ->      GROUP BY id, descripcion) T3 ON T1.id = T3.id
  9.     -> GROUP BY T1.id, T1.descripcion;
  10. +------+-------------+----------+----------+
  11. | id   | descripcion | total_t2 | total_t3 |
  12. +------+-------------+----------+----------+
  13. |    1 | uno         |        1 |        3 |
  14. |    2 | dos         |        1 |        1 |
  15. |    3 | tres        |     NULL |     NULL |
  16. +------+-------------+----------+----------+
  17. 3 rows in set (0.00 sec)

Dale un vistazo y nos comentas.

Saludos
Leo.