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

Al hacer LEFT JOIN se me Altera el SUM

Estas en el tema de Al hacer LEFT JOIN se me Altera el SUM en el foro de Mysql en Foros del Web. Bueno, mi duda es respecto al LEFT JOIN, cuando hago el SELECT se me altera solamente el resultado del primer registro.. @import url("http://static.forosdelweb.com/clientscript/vbulletin_css/geshi.css"); Código MySQL: ...
  #1 (permalink)  
Antiguo 01/11/2012, 09:00
 
Fecha de Ingreso: agosto-2012
Mensajes: 8
Antigüedad: 12 años, 3 meses
Puntos: 0
Pregunta Al hacer LEFT JOIN se me Altera el SUM

Bueno, mi duda es respecto al LEFT JOIN, cuando hago el SELECT se me altera solamente el resultado del primer registro..

Código MySQL:
Ver original
  1. SELECT  SUM(Total) Total, c.Nombre
  2. FROM tblfactura f
  3. INNER JOIN tblcliente c ON c.IdCliente=f.IdCliente
  4. GROUP BY f.IdCliente

Esta consulta me otorga
|Total | Nombre |
--------------------------------------
| 90229840 | Pedro |
| 59762000 | Juana |
| 16956345 | Homero |


Código MySQL:
Ver original
  1. SELECT  SUM(Total) Total, c.Nombre, SUM(Valor) Pagado
  2. FROM tblfactura f
  3. INNER JOIN tblcliente c ON c.IdCliente=f.IdCliente
  4. LEFT JOIN tblpagosxfactura pxf ON pxf.NroFactura=f.NroFactura
  5. GROUP BY f.IdCliente

Con esta consulta ya se me altera el primer registro pero los demas siguen igual... a qué se debe??

|Total | Nombre | Pagado |
---------------------------------------------------------
| 178529990| Pedro | 30047100|
| 59762000 | Juana | null |
| 16956345 | Homero | null |


Gracias por su colaboracion
  #2 (permalink)  
Antiguo 01/11/2012, 09:22
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 10 meses
Puntos: 447
Respuesta: Al hacer LEFT JOIN se me Altera el SUM

Hola verdolaga1989:

Cuando sumas un NULL a cualquier número el resultado es NULL:

Código MySQL:
Ver original
  1. mysql> SELECT 10 + NULL;
  2. +-----------+
  3. | 10 + NULL |
  4. +-----------+
  5. |      NULL |
  6. +-----------+
  7. 1 row in set (0.01 sec)

en tu correo no especificas cuál es la estructura de tus tablas, pero supongo que el campo VALOR corresponde a tu tabla tblpagosxfactura ... al poner un LEFT JOIN es posible que estés arrojando registros NULL. Puedes probar así:

Código:
SELECT *SUM(Total) Total, c.Nombre, SUM(IFNULL(Valor, 0)) Pagado
FROM tblfactura f
INNER JOIN tblcliente c ON c.IdCliente=f.IdCliente
LEFT JOIN tblpagosxfactura pxf ON pxf.NroFactura=f.NroFactura
GROUP BY f.IdCliente
Lo único que haces es sumar un CERO en lugar de sumar un vacio:

Código MySQL:
Ver original
  1. mysql> SELECT 10 + IFNULL(NULL, 0);
  2. +----------------------+
  3. | 10 + IFNULL(NULL, 0) |
  4. +----------------------+
  5. |                   10 |
  6. +----------------------+
  7. 1 row in set (0.03 sec)

Saludos
Leo.
  #3 (permalink)  
Antiguo 01/11/2012, 09:30
 
Fecha de Ingreso: agosto-2012
Mensajes: 8
Antigüedad: 12 años, 3 meses
Puntos: 0
Respuesta: Al hacer LEFT JOIN se me Altera el SUM

Gracias Leo por responder...

Asi es el campo Valor corresponde a la tabla tblpagosxfactura... el problema que tengo es que al sumar el Total de cada factura por cliente debe ser 90229840 para Pedro.. pero al hacer el LEFT JOIN con tblpagosxfactura se altera ese total por 178529990... los totales de Juana y Homero siguen siendo los mismos.. solo se me altera el primer registro... lo de los null es porque Juana y Homero no han realizado pagos hasta la fecha, el unico que ha pagado es Pedro..

No entiendo porque se altera solo el primer registro de la consulta..
  #4 (permalink)  
Antiguo 01/11/2012, 10:37
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 10 meses
Puntos: 447
Respuesta: Al hacer LEFT JOIN se me Altera el SUM

Por qué no empiezas por decirnos exactamente cuál es la estructura de tus tablas y nos pones algunos datos de ejemplo??? creo que tienes un problemas con las relaciones y es posible que se esté realizando una especie de producto cartesiano entre las tablas, pero sin más información no puedo darte un diagnóstico más puntual...

Saludos
Leo.
  #5 (permalink)  
Antiguo 01/11/2012, 11:14
 
Fecha de Ingreso: agosto-2012
Mensajes: 8
Antigüedad: 12 años, 3 meses
Puntos: 0
Respuesta: Al hacer LEFT JOIN se me Altera el SUM

Tabla Cliente
Código MySQL:
Ver original
  1. CREATE TABLE IF NOT EXISTS `tblcliente` (
  2.   `IdCliente` int(10) unsigned NOT NULL auto_increment,
  3.   `Nombre` varchar(30) collate utf8_spanish_ci NOT NULL,
  4.   `Telefono` varchar(15) collate utf8_spanish_ci NOT NULL,
  5.   `eMail` varchar(50) collate utf8_spanish_ci NOT NULL,
  6.   `Ciudad` varchar(30) collate utf8_spanish_ci NOT NULL,
  7.   `Estado` varchar(10) collate utf8_spanish_ci NOT NULL,
  8.   PRIMARY KEY  (`IdCliente`)
  9. ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci AUTO_INCREMENT=11 ;
  10.  
  11. INSERT INTO `tblcliente` (`IdCliente`, `Nombre`, `Telefono`, `eMail`, `Ciudad`, `Estado`) VALUES
  12. (1, 'Pedro', '2136356', '[email protected]', 'Medellín', 'Activo'),
  13. (2, 'Juana', '5342254', '[email protected]', 'Cali', 'Activo'),
  14. (3, 'Homero', '4563422', '[email protected]', 'Medellín', 'Activo');

Tabla Factura
Código MySQL:
Ver original
  1. CREATE TABLE IF NOT EXISTS `tblfactura` (
  2.   `IdCliente` int(10) unsigned NOT NULL,
  3.   `Fecha` date NOT NULL,
  4.   `Total` int(11) NOT NULL,
  5.   `TNeto` int(10) unsigned NOT NULL,
  6.   `IVA` double default NULL,
  7.   `Descuento` double default NULL,
  8.   `Estado` varchar(10) collate utf8_spanish_ci NOT NULL,
  9.   `Moneda` varchar(3) collate utf8_spanish_ci NOT NULL,
  10.   `Descripcion` text collate utf8_spanish_ci NOT NULL,
  11.   PRIMARY KEY  (`NroFactura`),
  12.   KEY `IdCliente` (`IdCliente`),
  13.   KEY `Moneda` (`Moneda`)
  14. ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci AUTO_INCREMENT=16 ;
  15.  
  16. INSERT INTO `tblfactura` (`NroFactura`, `IdCliente`, `Fecha`, `Total`, `TNeto`, `IVA`, `Descuento`, `Estado`, `Moneda`, `Descripcion`) VALUES
  17. 00001, 1, '2012-10-05', 44148000, 44148000, 0, 0, 'Active', 'COP', 'Venta 3 Graham, 2 Rolex y 1 Hublot'),
  18. (00002, 3, '2012-10-05', 59762000, 59762000, 0, 0, 'Active', 'COP', 'Venta Prueba'),
  19. (00004, 1, '2012-10-05', 4150, 4150, 0, 0, 'Active', 'USD', 'Venta Rolex'),
  20. (00005, 1, '2012-10-08', 97500, 100000, 0, 2.5, 'Active', 'COP', 'factura con descuento del 2.5%'),
  21. (00007, 1, '2012-10-01', 21253260, 21687000, 0, 2, 'Active', 'COP', 'Prueba'),
  22. (00008, 1, '2012-10-19', 24716430, 27462700, 0, 10, 'Active', 'COP', 'Prueba varios items'),
  23. (00015, 1, '2012-10-24', 10500, 10500, 0, 0, 'Active', 'USD', 'Venta 3 rolex en USD');
  24. (00011, 3, '2012-10-19', 16956345, 17535000, 0, 3.3, 'Active', 'COP', 'factura venta actualizar stock'),

Tabla Pagos por Factura
Código MySQL:
Ver original
  1. CREATE TABLE IF NOT EXISTS `tblpagosxfactura` (
  2.   `NroFactura` int(5) unsigned zerofill NOT NULL,
  3.   `Valor` int(11) unsigned NOT NULL,
  4.   `Fecha` date NOT NULL,
  5.   `Descripcion` text collate utf8_spanish_ci,
  6.   `TipoPago` varchar(10) collate utf8_spanish_ci NOT NULL,
  7.   `Moneda` varchar(3) collate utf8_spanish_ci NOT NULL,
  8.   PRIMARY KEY  (`NroPago`),
  9.   KEY `NroFactura` (`NroFactura`),
  10.   KEY `Moneda` (`Moneda`)
  11. ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci AUTO_INCREMENT=11 ;
  12.  
  13. INSERT INTO `tblpagosxfactura` (`NroPago`, `NroFactura`, `Valor`, `Fecha`, `Descripcion`, `TipoPago`, `Moneda`) VALUES
  14. (1, 00001, 10000000, '2012-10-05', 'Pago en efectivo a la Fac Nro. 00001  por el valor de 10''000.000', 'Cash', 'COP'),
  15. (4, 00001, 10000000, '2012-10-16', 'Pago en cheque por 10''000.000', 'Check', 'COP'),
  16. (7, 00001, 5000000, '2012-10-19', 'Pago en efectivo', 'Cash', 'COP');

La tabla tblcliente se relaciona con tblfactura por medio de IdCliente y tblfactura se relaciona con tblpagosxfactura por medio de NroFactura
  #6 (permalink)  
Antiguo 01/11/2012, 13:05
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 10 meses
Puntos: 447
Respuesta: Al hacer LEFT JOIN se me Altera el SUM

Hola de nuevo verdolaga1989:

Efectivamente, tienes un problema con las relaciones, pero no tanto que falte expresar alguna condición, sino en cuanto a la cardinalidad... de acuerdo a los datos que pones de ejemplo (y después de corregir algunos errores en las sentencias que pusiste) puedo observa que una factura puede tener N pagos... aquí es donde está el problema... al hacer la relación como lo estás haciendo, ESTÁS DUPLICANDO EL MONTO DE LA FACTURA...

Observa este ejemplo:

Código MySQL:
Ver original
  1. mysql> SELECT * FROM tabla1;
  2. +---------+-------------+-------+
  3. | factura | descripcion | total |
  4. +---------+-------------+-------+
  5. |       1 | uno         |    10 |
  6. |       2 | dos         |    30 |
  7. +---------+-------------+-------+
  8. 2 rows in set (0.00 sec)
  9.  
  10. mysql> SELECT * FROM tabla2;
  11. +------+---------+-------+
  12. | pago | factura | valor |
  13. +------+---------+-------+
  14. |    1 |       1 |     5 |
  15. |    2 |       1 |     1 |
  16. |    3 |       1 |     2 |
  17. |    4 |       2 |    15 |
  18. |    5 |       2 |     5 |
  19. +------+---------+-------+
  20. 5 rows in set (0.00 sec)
  21.  
  22. mysql> SELECT * FROM tabla1 INNER JOIN tabla2 ON tabla1.factura = tabla2.factura
  23. ;
  24. +---------+-------------+-------+------+---------+-------+
  25. | factura | descripcion | total | pago | factura | valor |
  26. +---------+-------------+-------+------+---------+-------+
  27. |       1 | uno         |    10 |    1 |       1 |     5 |
  28. |       1 | uno         |    10 |    2 |       1 |     1 |
  29. |       1 | uno         |    10 |    3 |       1 |     2 |
  30. |       2 | dos         |    30 |    4 |       2 |    15 |
  31. |       2 | dos         |    30 |    5 |       2 |     5 |
  32. +---------+-------------+-------+------+---------+-------+
  33. 5 rows in set (0.00 sec)

Observa que aquí no estoy agrupando, pero observa como los montos de la tabla1 SE DUPLICAN POR CADA REGISTRO QUE APARECE EN LA TABLA2... la relación en estas tablas (como en tu caso) es de 1 a N, pero para evitar esto tendrías que hacer una relación 1 a 1... ¿cómo logras eso? consolidando o agrupando los elementos de la tabla2 ANTES DE HACER EL JOIN... es decir, haces algo como esto:

Código MySQL:
Ver original
  1. mysql> SELECT * FROM tabla1
  2.     -> INNER JOIN ( SELECT factura, SUM(valor) valor
  3.     ->              FROM tabla2
  4.     ->              GROUP BY factura ) T2
  5.     -> ON tabla1.factura = t2.factura;
  6. +---------+-------------+-------+---------+-------+
  7. | factura | descripcion | total | factura | valor |
  8. +---------+-------------+-------+---------+-------+
  9. |       1 | uno         |    10 |       1 |     8 |
  10. |       2 | dos         |    30 |       2 |    20 |
  11. +---------+-------------+-------+---------+-------+
  12. 2 rows in set (0.00 sec)

Observa la consulta marcada como T2... aquí se realiza la agrupación POR FACTURA, por lo tanto la relación entre esta tabla y la tabla 1 AHORA SI ES 1 A 1...

Tú tendrías que hacer algo lo mismo, es decir, algo como esto:

Código:
SELECT 
  c.idCliente,
   c.nombre, 
  SUM(f.total) total, 
  SUM(IFNULL(p.pagado, 0)) pagado
FROM tblcliente c
INNER JOIN tblfactura f  ON c.IdCliente=f.IdCliente
LEFT JOIN ( SELECT NroFactura, SUM(valor) pagado 
                   FROM tblpagosxfactura GROUP BY NroFactura) p 
ON f.NroFactura = p.NroFactura
GROUP BY c.IdCliente, c.nombre
Observa la consulta marcada con rojo, esto sirve para consolidar (agrupar) todos los pagos de cada factura...

Haz la prueba y nos comentas.

Saludos
Leo.
  #7 (permalink)  
Antiguo 01/11/2012, 20:12
 
Fecha de Ingreso: agosto-2012
Mensajes: 8
Antigüedad: 12 años, 3 meses
Puntos: 0
Respuesta: Al hacer LEFT JOIN se me Altera el SUM

Funciona perfecto !!! .. el código queda así

Código MySQL:
Ver original
  1. SELECT c.Nombre, SUM(f.Total) Total, SUM(IFNULL(p.pagado, 0)) Pagado, (SUM(f.Total)- SUM(IFNULL(p.pagado, 0))) Debe, FORMAT((SUM(f.Total)- SUM(IFNULL(p.pagado, 0))),0) TotalDebe2
  2. FROM tblcliente c
  3. INNER JOIN tblfactura f  ON c.IdCliente=f.IdCliente
  4. LEFT JOIN ( SELECT NroFactura, SUM(Valor) Pagado
  5.         FROM tblpagosxfactura GROUP BY NroFactura) p
  6.                 ON f.NroFactura = p.NroFactura
  7. GROUP BY c.IdCliente

Muchisimas gracias Leo !! me sacaste de tremendo lio

Etiquetas: join, left, select, sum
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 10:58.