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

Problema con access

Estas en el tema de Problema con access en el foro de Bases de Datos General en Foros del Web. Hola a todos. Tengo una base de datos en access 2010 en la cual quiero saber las ventas que tuve en un determinado mes para ...
  #1 (permalink)  
Antiguo 25/07/2012, 16:45
 
Fecha de Ingreso: mayo-2011
Mensajes: 12
Antigüedad: 13 años
Puntos: 0
Problema con access

Hola a todos. Tengo una base de datos en access 2010 en la cual quiero saber las ventas que tuve en un determinado mes para saber si gano o pierdo dinero restandole después los gastos. La cuestión es que si un mes no tengo ninguna venta no sé que me devuelve para poder tratarlo y sumarle o restarle 0 en el resultado del mes. No se si se entiende la pregunta. La consulta que tengo es la siguiente:
Código SQL:
Ver original
  1. SELECT SUM([VENTA]![IMPORTE_TOTAL]) AS [Total facturas emitidas],
  2. MONTH([VENTA].[FECHA_DESCARGA]) AS Mes,
  3. YEAR([VENTA].[FECHA_DESCARGA]) AS Año
  4. FROM VENTA
  5. GROUP BY MONTH([VENTA].[FECHA_DESCARGA]), YEAR([VENTA].[FECHA_DESCARGA])
  6. HAVING (((MONTH([VENTA].[FECHA_DESCARGA]))=[Escribe número de mes])
  7. AND ((YEAR([VENTA].[FECHA_DESCARGA]))=[Escribe año]));

Un saludo

Última edición por gnzsoloyo; 28/07/2012 a las 08:28 Razón: No usó las etiquetas de código.
  #2 (permalink)  
Antiguo 27/07/2012, 10:56
 
Fecha de Ingreso: febrero-2010
Ubicación: México
Mensajes: 738
Antigüedad: 14 años, 2 meses
Puntos: 37
Respuesta: Problema con access

Que tal chinpun

Normalmente cuando ser realizan este tipo de operaciones se agrega el ISNULL(SUM(Campo), 0) esto para evitar que la consulta retorne valores NULL.

Saludos.
__________________
http://ka0stj.wordpress.com/
  #3 (permalink)  
Antiguo 28/07/2012, 08:26
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: Problema con access

Un detalle a tener en cuenta: El HAVING se usa generalmente cuando quieres comparar un dato contra el valor de una función agregada (SUM, MAX, AVG, MIN, etc), pero no para comparar un campo contra una constante, como el numero de mes o año que buscas. En ese caso es preferible hacerlo en el WHERE, que interviene antes en la lógica del plan de consulta.
El HAVING es un filtro final, no inicial, por lo que la escritura que propones es de baja performance.
La idea sería, entonces:
Código SQL:
Ver original
  1. SELECT
  2.     SUM([VENTA]![IMPORTE_TOTAL]) AS [Total facturas emitidas],
  3.     MONTH([VENTA].[FECHA_DESCARGA]) AS Mes,
  4.     YEAR([VENTA].[FECHA_DESCARGA]) AS Año
  5. FROM
  6.     VENTA
  7. WHERE (((MONTH([VENTA].[FECHA_DESCARGA]))=[Escribe número de mes]) AND ((YEAR([VENTA].[FECHA_DESCARGA]))=[Escribe año]))
  8. GROUP BY
  9.     MONTH([VENTA].[FECHA_DESCARGA]), YEAR([VENTA].[FECHA_DESCARGA]);
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #4 (permalink)  
Antiguo 28/07/2012, 14:17
 
Fecha de Ingreso: mayo-2011
Mensajes: 12
Antigüedad: 13 años
Puntos: 0
Respuesta: Problema con access

Hola, gracias por las respuestas, he cambiado la consulta según me dijiste gnzsoloyo, pero con eso no me resuelve el problema que tengo. Cuando pongo un mes en el que no tengo datos la consulta sigue saliendo vacía.
kaOstj he puesto el isnull pero combinado con el iif ya que el isnull solo compara la expresión pero me sigue sin funcionar, la consulta que tengo ahora es la siguiente:

Código SQL:
Ver original
  1. SELECT IIf(IsNull(SUM([VENTA]![IMPORTE_TOTAL])),0,SUM([VENTA]![IMPORTE_TOTAL])) AS [Total facturas emitidas],
  2. MONTH([VENTA].[FECHA_DESCARGA]) AS Mes,
  3. YEAR([VENTA].[FECHA_DESCARGA]) AS Año
  4. FROM VENTA
  5. WHERE (((MONTH([VENTA].[FECHA_DESCARGA]))=[Escribe número de mes]) AND ((YEAR([VENTA].[FECHA_DESCARGA]))=[Escribe año]))
  6. GROUP BY MONTH([VENTA].[FECHA_DESCARGA]), YEAR([VENTA].[FECHA_DESCARGA]);

Lo que quiero es que si no existen datos en el mes que escribo, que me salga 0 en importe total y el mes y el año que escribo.

Última edición por gnzsoloyo; 28/07/2012 a las 15:21 Razón: No usó las etiquetas de códigos.
  #5 (permalink)  
Antiguo 28/07/2012, 15:35
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: Problema con access

Cita:
Hola, gracias por las respuestas, he cambiado la consulta según me dijiste gnzsoloyo, pero con eso no me resuelve el problema que tengo.
Yo en ningún momento he dicho que la consulta fuera a resolverte ningún problema. Yo estaba hablando de performance, no de resultados de consulta. Son cosas distintas.
A lo que me refería es que como el HAVING se aplica luego de obtener la tabla resultados y no durante el proceso global, no es eficiente plantear un filtrado de datos en él que no sea algo muy preciso, y que no abarque la totalidad de los casos, o bien como solución para casos donde se necesita aplicar una función agregada en las condiciones, cosa que ningún DBMS te permite hacer en el WHERE.
Siempre que necesites realizar un filtrado de datos usando cosas como MAX(), MIN(), AVG, SUM(), etc., se hace en el HAVING, pero tu estabas comparando constantes contra valores de funciones no agregadas, y eso se hace en el WHERE.
¿Se comprende la idea?

Cita:
Cuando pongo un mes en el que no tengo datos la consulta sigue saliendo vacía.
Ese es un error conceptual bastante difundido entre programadores, porque no están habituados a la lógica de las bases de datos.
El problema es que una consulta SQL te devuelve tablas, opera con tablas, almacena datos en tablas, y devuelve los datos que existen en las tablas.
Una consulta a la base de datos no puede realizar operaciones de ningún tipo con datos que no existen en la base.

Primero: Para poder realizar una comparación tal que te devuelva lo que no hay en una tabla, debe ser comparado con lo que haya en otra tabla.
Segundo: Eso significa que para poder hacerlo deberías estar usando un JOIN contra otra tabla que proveyese de los datos raíz a comparar: Los datos de los meses... y no los tienes.

En resumen, tienes dos formas de solucionar las cosas:

1) Usas una tabla que contenga todos y cada uno de los meses del período que vas a verificar, y realizas un LEFT JOIN entre esa tabla y la tabla de ventas.

2) Haces lo que hacen todos los programas: Construyes esos valores visualmente en el formulario, llenando programáticamente los huecos de información con datos para mostrar, que serían aquellos que la base no te puede devolver.

El cómo haces esto último, es tema de programación y OFF-TOPIC de este foro. Deberás resolverlo en el lenguaje que uses para mostrar los datos.

Tip final: Por favor, usa los etiquetados para códigos que te muestra el combo "Highlight", para que tus códigos fuentes sean más legibles.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #6 (permalink)  
Antiguo 30/07/2012, 14:19
 
Fecha de Ingreso: mayo-2011
Mensajes: 12
Antigüedad: 13 años
Puntos: 0
Respuesta: Problema con access

He creado una tabla para dia, otra para mes y otra para año, el problema ahora es que no se como realizar el join, podrías echarme un cable?
Se podría hacer también con una macro? Como bien acertaste soy programador y se me da mejor que access
  #7 (permalink)  
Antiguo 01/08/2012, 16:24
 
Fecha de Ingreso: mayo-2011
Mensajes: 12
Antigüedad: 13 años
Puntos: 0
Respuesta: Problema con access

Ya he conseguido hacer la consulta con el left join. Muchas gracias.
Me podrías ayudar a hacer la consulta en codigo VB para ejecutarla con una macro?

Etiquetas: access, der
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.