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

Sum() y agrupar por tipo

Estas en el tema de Sum() y agrupar por tipo en el foro de Mysql en Foros del Web. Hola a todos, tengo un problema con la optimización de una consulta. tengo una tabla "facturas", en la cual almaceno varios tipos diferentes de facturas ...
  #1 (permalink)  
Antiguo 27/08/2008, 14:56
 
Fecha de Ingreso: diciembre-2004
Mensajes: 278
Antigüedad: 19 años, 4 meses
Puntos: 0
Sum() y agrupar por tipo

Hola a todos, tengo un problema con la optimización de una consulta.
tengo una tabla "facturas", en la cual almaceno varios tipos diferentes de facturas (campo id_tipo_factura) y quiero sumar el importe de cada tipo por separado.
Hasta ahora hago lo siguiente:

Código:
SELECT SUM( f1.total_factura ) AS total_pedidos,
					SUM( f2.total_factura) AS total_generales,
					SUM( f3.total_factura) AS total_emitidas
FROM `facturas` AS f1, `facturas` AS f2, `facturas` AS f3
WHERE
f1.id_tipo_factura=2 AND 
f2.id_tipo_factura=3 AND
f3.id_tipo_factura=1 AND
YEAR(f1.fecha)='2008' AND
YEAR(f2.fecha)='2008' AND
YEAR(f3.fecha)='2008'
Bien, esta consulta funciona pero es demasiado lenta sobre mi base de datos (0.5 sec).
Habia pensado hacer algo así para hacerla mas ràpida:
Código:
SELECT SUM(total_factura)
FROM facturas
WHERE YEAR(fecha)='2008' GROUP BY id_tipo_factura
Evidentemente no devuelve los mismos resultados, luego no funciona correctamente.
Alguien ve una solución?
  #2 (permalink)  
Antiguo 27/08/2008, 19:52
Avatar de 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: Sum() y agrupar por tipo

Código:
SELECT 
	SUM(IF(id_tipo_factura=2, total_factura,0) total_pedidos,
	SUM(IF(id_tipo_factura=3, total_factura,0) total_generales,
	SUM(IF(id_tipo_factura=1, total_factura,0) total_emitidas
FROM facturas
WHERE
	YEAR(fecha)=2008;
1. La cláusula AS es innecesaria para crear alias. MySQL asume que el siguiente string a un campo del SELECT o de una tabla, o al paréntesis de cierre de una subconsulta es un ALIAS. El AS era parte del estándar de ANSI-SQL, pero todos los motores lo eliminaron como exigencia desde hace mucho. Ahora es opcional, y se conserva por cuestiones de compatibilidad con servidores viejos que puedan estar corriendo.

2. SI vas a hacer un JOIN entre tablas, asegúrate de determinar los campos de relación entre las tuplas, para que de esa forma no esté operando como un producto cartesiano. Ese era uno de tus problemas (falta de selectividad).

3. Si el campo contiene números, no lo compares con un string sino con otro número, de lo contrario obligas a MySQL a hacer una conversión implícita y eso resiente la performance cuando se trata de grandes cantidades de tuplas (en pocas no lo notarás).
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #3 (permalink)  
Antiguo 28/08/2008, 09:00
 
Fecha de Ingreso: diciembre-2004
Mensajes: 278
Antigüedad: 19 años, 4 meses
Puntos: 0
Respuesta: Sum() y agrupar por tipo

Gracias por tu respuesta!
De todas maneras un apunte... la consulta que resulta me daba resultados erroneos era la primera!!!

Con mi segunda sentencia obtengo los mismos resultados que con tu propuesta...

Cita:
1. La cláusula AS es innecesaria para crear alias. MySQL asume que el siguiente string a un campo del SELECT o de una tabla, o al paréntesis de cierre de una subconsulta es un ALIAS. El AS era parte del estándar de ANSI-SQL, pero todos los motores lo eliminaron como exigencia desde hace mucho. Ahora es opcional, y se conserva por cuestiones de compatibilidad con servidores viejos que puedan estar corriendo.
No lo sabía, pero si no le molesta a MySQL seguiré poniéndolo, pues lo veo más claro.

Cita:
3. Si el campo contiene números, no lo compares con un string sino con otro número, de lo contrario obligas a MySQL a hacer una conversión implícita y eso resiente la performance cuando se trata de grandes cantidades de tuplas (en pocas no lo notarás).
Se aplica también a los campos DATE ?
  #4 (permalink)  
Antiguo 28/08/2008, 09:56
Avatar de 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: Sum() y agrupar por tipo

Cita:
Con mi segunda sentencia obtengo los mismos resultados que con tu propuesta...
No debería ser así, porque con tu segunda sentencia obtienes la suma del total de factuación, pero no discriminada por tipo.
Mientras que en la que te propongo, se suman por separado según el tipo de factura declarado en el campo id_tipo_factura. En otras palabras, debería devolver tres campos con la suma de cada tipo.

respecto a lo otro: Todas las conversiones implícitas afectan la performance. Por eso no son buena idea, a menos que no tengas otra solución.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #5 (permalink)  
Antiguo 28/08/2008, 10:37
 
Fecha de Ingreso: diciembre-2004
Mensajes: 278
Antigüedad: 19 años, 4 meses
Puntos: 0
Respuesta: Sum() y agrupar por tipo

Cita:
Iniciado por gnzsoloyo Ver Mensaje
No debería ser así, porque con tu segunda sentencia obtienes la suma del total de factuación, pero no discriminada por tipo.
Mientras que en la que te propongo, se suman por separado según el tipo de factura declarado en el campo id_tipo_factura. En otras palabras, debería devolver tres campos con la suma de cada tipo.
No lo dudo, pero el resultado es ese (ojo, no digo que esté bien hecho).
Quizá el "GROUP BY id_tipo_factura" que efectúo genera el mismo efecto que los tres SUM() separados.
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 08:29.