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

[SOLUCIONADO] Consulta usando LEFT JOIN

Estas en el tema de Consulta usando LEFT JOIN en el foro de Mysql en Foros del Web. Buenas gente, llegue al foro buscando una solucion para mi problema (y no la encontre jejejeje). El tema es asi, tengo 3 tablas, planillaDiaria, empleados ...
  #1 (permalink)  
Antiguo 10/01/2013, 15:41
 
Fecha de Ingreso: enero-2013
Mensajes: 14
Antigüedad: 11 años, 3 meses
Puntos: 0
Consulta usando LEFT JOIN

Buenas gente, llegue al foro buscando una solucion para mi problema (y no la encontre jejejeje).

El tema es asi, tengo 3 tablas, planillaDiaria, empleados y vales, las tres se relacionan por el id del empleado.

La consulta que intento hacer es listar todos los empleados, sumando el sueldo de las planillas correspondientes a c/u y sumar la cantidad de dinero en vales tambien de cada uno.

Intente varias consultas pero siempre tengo el mismo error (si un empleado tiene 2 planillas y un vale de $ 100, me duplica el vale a $ 200, si tuviera 3 planillas me lo triplica y asi sucesivamente) la ultima consulta que intente es esta:

"SELECT SUM(plani.sueldo) AS neto, emp.nombreApellido, SUM(vale.importeVale) AS descuento FROM planillaDiaria AS plani
LEFT JOIN empleados AS emp ON plani.idEmpleado=emp.id LEFT JOIN vales AS vale ON emp.id=vale.idEmpleado
AND date(vale.fechaVale) between '".$liqModel->getFechaDesde()."' AND '".$liqModel->getFechaHasta()."'
AND vale.idEmpleado=emp.id
WHERE date(plani.fechaPlanilla) between '".$liqModel->getFechaDesde()."' AND '".$liqModel->getFechaHasta()."'
GROUP BY emp.id";

Si alguien me puede dar una idea del error que estoy comentiendo lo agradecere.

Saludos,
Matias.
  #2 (permalink)  
Antiguo 10/01/2013, 16:14
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 3 meses
Puntos: 447
Respuesta: Consulta usando LEFT JOIN

Hola sanymatu:

Este es un error bastante típico, me extraña que no hayas encontrado ninguna solución... pero bueno, vayamos por partes... para entender por qué te está ocurriendo esto, hay que recordar cómo funcionan los JOINS... supongamos que tienes estas tablas:

Código MySQL:
Ver original
  1. mysql> SELECT * FROM tabla1;
  2. +-------+--------+
  3. | id_t1 | nombre |
  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_t2 | id_t1 | planilla |
  14. +-------+-------+----------+
  15. |     1 |     1 |       15 |
  16. |     2 |     1 |       10 |
  17. |     3 |     1 |       12 |
  18. |     4 |     2 |        7 |
  19. |     5 |     2 |        3 |
  20. |     6 |     3 |        9 |
  21. |     7 |     3 |       21 |
  22. +-------+-------+----------+
  23. 7 rows in set (0.00 sec)
  24.  
  25. mysql> SELECT * FROM tabla3;
  26. +-------+-------+-------+
  27. | id_t3 | id_t1 | vales |
  28. +-------+-------+-------+
  29. |     1 |     1 |     2 |
  30. |     2 |     1 |     3 |
  31. |     3 |     2 |     5 |
  32. |     4 |     3 |    10 |
  33. +-------+-------+-------+
  34. 4 rows in set (0.00 sec)

Observa lo que pasa si haces un JOIN entre las tablas 2 y 3:

Código MySQL:
Ver original
  1. mysql> SELECT *
  2.     -> FROM tabla2 T2
  3.     -> INNER JOIN tabla3 T3 ON T3.id_t1 = T2.id_t1;
  4. +-------+-------+----------+-------+-------+-------+
  5. | id_t2 | id_t1 | planilla | id_t3 | id_t1 | vales |
  6. +-------+-------+----------+-------+-------+-------+
  7. |     1 |     1 |       15 |     1 |     1 |     2 |
  8. |     1 |     1 |       15 |     2 |     1 |     3 |
  9. |     2 |     1 |       10 |     1 |     1 |     2 |
  10. |     2 |     1 |       10 |     2 |     1 |     3 |
  11. |     3 |     1 |       12 |     1 |     1 |     2 |
  12. |     3 |     1 |       12 |     2 |     1 |     3 |
  13. |     4 |     2 |        7 |     3 |     2 |     5 |
  14. |     5 |     2 |        3 |     3 |     2 |     5 |
  15. |     6 |     3 |        9 |     4 |     3 |    10 |
  16. |     7 |     3 |       21 |     4 |     3 |    10 |
  17. +-------+-------+----------+-------+-------+-------+
  18. 10 rows in set (0.00 sec)

Aquí está la duplicidad. La relación entre la tabla1 y las tablas 2 y 3 es de 1 a n, pero entre las tablas 2 y 3 se convierte en una relación muchos a muchos.

Para evita esto, tienes que agrupar antes de hacer el JOIN... así:

Código MySQL:
Ver original
  1. mysql> SELECT T1.*, T2.total_planilla, T3.total_vales
  2.     -> FROM
  3.     ->   tabla1 T1
  4.     -> INNER JOIN
  5.     -> ( SELECT id_t1, SUM(planilla) total_planilla
  6.     ->   FROM tabla2
  7.     ->   GROUP BY id_t1) T2 ON T2.id_t1 = T1.id_t1
  8.     -> INNER JOIN
  9.     -> ( SELECT id_t1, SUM(vales) total_vales
  10.     ->   FROM tabla3
  11.     ->   GROUP BY id_t1) T3 ON T3.id_t1 = T1.id_t1;
  12. +-------+--------+----------------+-------------+
  13. | id_t1 | nombre | total_planilla | total_vales |
  14. +-------+--------+----------------+-------------+
  15. |     1 | UNO    |             37 |           5 |
  16. |     2 | DOS    |             10 |           5 |
  17. |     3 | TRES   |             30 |          10 |
  18. +-------+--------+----------------+-------------+
  19. 3 rows in set (0.00 sec)

Observa que la agrupación se realiza en una subconsulta:

Código:
( SELECT id_t1, SUM(planilla) total_planilla
   FROM tabla2
   GROUP BY id_t1) T2
De esta manera, la relación entre las tabla1 y la tabla2 pasa a ser una relación 1 a 1, lo mismo que la relación entre las tablas1 y tabla3. Dale un vistazo y si tienes dudas lo comentas en el foro.

Saludos
Leo.
  #3 (permalink)  
Antiguo 10/01/2013, 16:35
 
Fecha de Ingreso: enero-2013
Mensajes: 14
Antigüedad: 11 años, 3 meses
Puntos: 0
Respuesta: Consulta usando LEFT JOIN

leonardo_josue, muchisimas gracias, no encontre info porque no daba con la frase a buscar, ya lo tengo encaminado pero no me quedo muy claro voy a verlo mas tranquilo, lo que si vi es que con el inner join solo me trae los datos de los empleados que tienen vale, los que no, no los muestra, ahi deberia cambiar por JOIN LEFT?

Nuevamente muchas gracias por tu ayuda y tu tiempo!!!

Saludos,
Matias.
  #4 (permalink)  
Antiguo 10/01/2013, 17:02
 
Fecha de Ingreso: enero-2013
Mensajes: 14
Antigüedad: 11 años, 3 meses
Puntos: 0
Respuesta: Consulta usando LEFT JOIN

leonardo_josue, consegui el resultado deseado, muchisimas gracias.

Dejo la consulta por si alguien tiene un problema similar.

"SELECT emp.id, emp.nombreApellido, plani.totalSueldo, vale.totalVales
FROM empleados AS emp
INNER JOIN(SELECT plani.fechaPlanilla, plani.idEmpleado, SUM(plani.sueldo) AS totalSueldo
FROM planillaDiaria AS plani WHERE date(plani.fechaPlanilla) between '".$liqModel->getFechaDesde()."' AND '".$liqModel->getFechaHasta()."'
GROUP BY plani.idEmpleado) plani ON plani.idEmpleado=emp.id
LEFT JOIN(SELECT vale.idEmpleado, SUM(vale.importeVale) AS totalVales, vale.fechaVale
FROM vales AS vale GROUP BY vale.idEmpleado) vale ON vale.idEmpleado=emp.id
AND date(vale.fechaVale) between '".$liqModel->getFechaDesde()."' AND '".$liqModel->getFechaHasta()."'";

Etiquetas: join, left, select, tabla, usando
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 22:45.