Ver Mensaje Individual
  #3 (permalink)  
Antiguo 13/03/2010, 17:01
Avatar de gnzsoloyo
gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: Consulta sobre consulta a dos tablas...

Cita:
Las fechas las tengo en formato string (05/03/2010 por ejemplo)por eso aplico el substr.... Igual ahi no es el error, porque si hago la consulta separada la suma me la hace bien de todo lo que tengo en la columna.
En realidad, el hecho de que tengas una fecha como VARCHAR oCHAR, ya es un error de los que no se deben cometer. Es impráctico para las consultas, y sujeto a errores frecuentes, por defectos de validación en la entrada, lo que da lugar a errores de resultados en las consultas, que no son errores de lógica de la consulta, sino por datos "sucios".

Bien. suponiendo que los datos de fecha fueron debidamente validados antes de ingresarlos a la base, la consulta debería tener este formato, para ser correcto sintácticamente:

Código MySQL:
Ver original
  1. SELECT (T1.entrada - T2.salida) Saldos
  2.     (SELECT SUM(monto) entrada FROM ingresos WHERE YEAR(STR_TO_DATE(fechaAbono, '%d/%m/%Y')) = 2010) T1
  3.     JOIN
  4.     (SELECT SUM(monto) FROM gastos WHERE YEAR(STR_TO_DATE(fechaM, '%d/%m/%Y')) = 2010) T2;
Un JOIN (o la coma) usado entre dos tablas que no contienen los mismos datos, pero si contienen los mismos nombres de campos, te está dando como resultados errores de resultados, o como mínimo generando un producto cartesiano, que en definitiva es una consulta sin optimización, lo cual también es un error.

Me explico mejor: En tu escenario:
Código MySQL:
Ver original
  1. SELECT SUM( ingresos.monto ) - SUM( gastos.monto ) AS Saldos
  2. FROM ingresos, gastos
  3. WHERE substr( ingresos.fechaAbono, 7, 4 ) =2010 && substr( gastos.fechaM, 7, 4 ) =2010
el FROM, como lo has puesto, le indica a MySQL que junte ambas tablas relacionándolas por medio del campo "monto". Aunque no se lo digas directamente, eso es lo que MySQL hace cuando encuentra en un JOIN un campo que en ambas tablas se denomina igual. Los intenta emparejar.
Con lo cual entremezcla campos que en realidad tienen datos diferentes (no es lo mismo un ingreso que un egreso). Normalmente esto se evita haciendo que los campos de las tablas se denominen diferente según la tabla a que pertenecen (monto_ingreso y monto_egreso, por ejemplo). Es una técnica mnemónica recomendada y habitual.

Ahora bien, yendo al segundo caso, al usar el mismo esquema anterior, el resultado sería:
Código MySQL:
Ver original
  1. SELECT (T1.entrada - T2.salida) Saldos
  2.     (SELECT SUM(monto) entrada FROM ingresos WHERE YEAR(STR_TO_DATE(fechaAbono, '%d/%m/%Y')) = 2010 AND MONTH(STR_TO_DATE(fechaAbono, '%d/%m/%Y')) = 3) T1
  3.     JOIN
  4.     (SELECT SUM(monto) FROM gastos WHERE YEAR(STR_TO_DATE(fechaM, '%d/%m/%Y'))= 2010 AND MONTH(STR_TO_DATE(fechaM, '%d/%m/%Y')) = 3) T2;

Lo que tienes que tener en cuenta es que STR_TO_DATE exige que el separador de fecha sea siempre el mismo que se indica (la "/" en este caso), ya que sino devolverá NULL. Eso es precisamente por lo que remarcaba lo de las validaciones. Si los datos no están correctamente validados, tanto esta función, como SUBSTR( ingresos.fechaAbono, 7, 4 ) te darán datos erróneos, ya que en el segundo caso, si en algún caso se ingresó "01/9/2010", también te daría un error, puesto que el mes sería de una cifra, no de dos, como se supone....

Espero que todo esto te sirva de algo.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)