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

[SOLUCIONADO] query para activos y pendientes

Estas en el tema de query para activos y pendientes en el foro de Mysql en Foros del Web. Hola, Quizás esta sea una pregunta sencilla, pero por más pruebas que hago no doy con el resultado y ya casi se me va el ...
  #1 (permalink)  
Antiguo 11/05/2014, 15:30
 
Fecha de Ingreso: noviembre-2001
Ubicación: México DF
Mensajes: 128
Antigüedad: 22 años, 4 meses
Puntos: 0
query para activos y pendientes

Hola,
Quizás esta sea una pregunta sencilla, pero por más pruebas que hago no doy con el resultado y ya casi se me va el tiempo de entrega del proyecto.
- Tengo una tabla "users", donde está toda la información del usuario
- Una tabla "groups" donde están los posibles grupos a los que puede pertenecer un usuario.
- Una tabla "users_groups" que enlaza "users" y "groups" donde registro los usuarios que ya están participando de un grupo determinado.
- Una tabla "pending" donde tengo los usuarios que han sido referidos, de ellos solo tengo nombre y email.
¿Qué quiero?
Quiero para cada grupo, su nombre, el número de miembros y el número de pendientes.

Los grupos y sus miembros los obtengo sin problemas con:

Código SQL:
Ver original
  1. SELECT g.`id_group`, g.`groupname`, COUNT(g.`groupname`) AS `members`
  2. FROM `groups` g
  3. LEFT JOIN `users_groups` ug ON (ug.`group_id` = g.`id_group`)
  4. GROUP BY g.`groupname`
  5.  
  6. resultado:
  7. id_group  groupname  members
  8.     19        aguilas         1
  9.     20          osos           2
  10.     18          gatos         1

Pero cuando quiero saber los pendientes ya me da un número equivocado:

Código SQL:
Ver original
  1. SELECT g.`id_group`, g.`groupname`, COUNT(g.`groupname`) AS `members`, COUNT(p.`name`) AS `pending`
  2. FROM `groups` g
  3. LEFT JOIN `users_groups` ug ON (ug.`group_id` = g.`id_group`)
  4. LEFT JOIN `pending` p ON (p.`group_id` = g.`id_group`)
  5. GROUP BY g.`groupname`, p.`name`
  6.  
  7. resultado:
  8. id_group  groupname  members  pending
  9.     19        aguilas           1             0
  10.     20          osos             2             0
  11.     18          gatos           1              1
  12.     18          gatos           1              1
  13.  
  14. esperado:
  15. id_group  groupname  members  pending
  16.     19        aguilas           1             0
  17.     20          osos             2             0
  18.     18          gatos           1              2

¿Qué estoy haciendo mal?
Saludos y gracias!!!
__________________
Nuedi Servicios SA de CV
http://www.nuedi.mx

Última edición por gnzsoloyo; 11/05/2014 a las 15:52
  #2 (permalink)  
Antiguo 12/05/2014, 12:31
 
Fecha de Ingreso: noviembre-2001
Ubicación: México DF
Mensajes: 128
Antigüedad: 22 años, 4 meses
Puntos: 0
Respuesta: query para activos y pendientes

Alguien que me pueda ayudar, por favor....
__________________
Nuedi Servicios SA de CV
http://www.nuedi.mx
  #3 (permalink)  
Antiguo 12/05/2014, 21:43
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 3 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.
  #4 (permalink)  
Antiguo 14/05/2014, 13:03
 
Fecha de Ingreso: noviembre-2001
Ubicación: México DF
Mensajes: 128
Antigüedad: 22 años, 4 meses
Puntos: 0
Respuesta: query para activos y pendientes

Que respuesta tan bien explicada!!! Gracias por haberte tomado el tiempo en dar una respuesta tan completa!!!
Déjame y reviso los ejemplos ahora con mis tablas y te comento que tal me fue.
Gracias!!!!!!!!!!
__________________
Nuedi Servicios SA de CV
http://www.nuedi.mx
  #5 (permalink)  
Antiguo 18/05/2014, 19:41
 
Fecha de Ingreso: noviembre-2001
Ubicación: México DF
Mensajes: 128
Antigüedad: 22 años, 4 meses
Puntos: 0
Respuesta: query para activos y pendientes

Pues sí funcionó a la perfección!! Gracias!!!
__________________
Nuedi Servicios SA de CV
http://www.nuedi.mx

Etiquetas: join, query, registro, select, tabla, usuarios
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:40.