PDA

Ver la Versión Completa : Complicada consulta


mosorio
11-08-2003, 22:36:07
Hola compañeros!
No se si se pueda hacer esta consulta o si se deba hacer por separado, pero espero me ayuden.

Tengo la siguiente tabla:

Movimientos
IdMovimiento, Valor, Fecha, Hora, IdTipoMov, Registro


En esta tengo almacenado todos los movimientos que se efectuen en el programa, como ventas, pagos, etc.
Lo que necesito es hacer una consulta que me arroje el total, partiendo de una fecha y la hora de ese registro y me sume todos los valores que se encuentren hasta el último.

Tengo que decir que el movimiento de partida es una apertura que tiene como código 5, Ejemplo: Una apertura con los datos

12, 18.25, 30/07/2003, 9:30, 5, 1

Registros sucesivos después de la apertura
13, 25.55, 30/07/2003, 10:10, 2, 7
14, 30.65, 30/07/2003, 10:25, 2, 8
15, 68.14, 30/07/2003, 11:45, 2, 9


Ahora el registro 16 que se generaría sería el cierre.

16, 142.59, 30/07/2003, 14:10, 6, 2


Pueden haber tantos cierres como aperturas, esto ya lo controlo, deben ser par. Pero cuando se vaya a efectuar el cierre o este registro que pretendo generar debe tomar el conteo a partir de la última apertura.
Estaba pensando en hacer una consulta anidada pero no se ni por donde comenzar, la verdad no soy muy ducho en hacer consultas, pero en hacer normalizaciones de BD me defiendo bastante.
Claro esta que hay muchas cosas que mejorar en esta tabla y en la aplicación, pero acepto propuestas, pero primero quiero resolver esto.

Gracias de antemano.

andres1569
12-08-2003, 18:11:21
Hola:

Si a la hora de hacer el registro de cierre, éste debe totalizar todos los registros desde una fecha/Hora hasta el actual, no es complicado de implementar:

SELECT SUM(Valor) as TOTAL
FROM MOVIMIENTOS
WHERE FECHA > :FechaIni OR
(FECHA = :FechaIni AND HORA >= :HoraIni)

donde le pasas la fecha y hora inicial en los parámetros :FechaIni y :HoraIni. Todo esto suponiendo que sepas la fecha y hora desde la que quieras totalizar y suponiendo que todos los registros introducidos desde esa Fecha/Hora pertenezcan a la misma operación Apertura/Cierre.

Otra cosa, si no sabes de antemano la Fecha y Hora inicial, yo haría en primer lugar la subconsulta que me devolviera la última apertura, almacenaría en sendas variables los valores de Fecha y Hora, y luego lanzaría la consulta que te he puesto al principio. Hacer esto mediante una consulta anidada (que repetiría para cada tupla la misma subconsulta, es bastante más lento, salvo que no tengas más remedio que hacerlo así). Si usas tablas planas, puedes lanzar desde Delphi las dos consultas, una detrás de otra. Y si usas motores SQL, lo puedes meter todo dentro de un procedimiento almacenado que se lance a la hora de grabar el cierre, por ejemplo.

La siguiente consulta presupone que los registros guardan un orden correlativo (de menor a mayor) en el campo IdMovimiento; si es el campo Registro, lo cambias y ya está. Si ninguno de los dos está en ese orden, habría que buscar la fecha/Hora más reciente (mayor) pero, es algo más complicado porque puede haber dos aperturas el mismo día y habría que emplear algún truco para obtener la mayor (quizás sumando fecha y hora, o bien ordenando el resultado por hora y cogiendo el último registro obtenido)

SELECT MAX(IDMOVIMIENTO) as MovIni, FECHA, HORA
FROM MOVIMIENTOS
WHERE IDTIPOMOV = 5
GROUP BY FECHA, HORA

Con esto tenemos la fecha y hora de la última apertura, basta con pasarle ambos parámetros a la consulta inicial; aunque ahora me doy cuenta de que si tenemos ordenada la tabla por idmovimiento, el WHERE de la primera consulta podría basarse en este campo:

SELECT SUM(Valor) as TOTAL
FROM MOVIMIENTOS
WHERE IDMOVIMIENTO >= :MovIni

¿Es esto lo que deseas? Espero no haberte liado con este rollo.

Saludos

mosorio
12-08-2003, 19:02:50
Hola Andres!

Muchas gracias por la respuesta, no la he probado pero creo que es la idea, ya he encontrado la solución, bueno eso creo, cuando llegue a casa intentare implementarla para obtener lo que necesito, pero primero debo organizar mis ideas.
La consulta se puede resolver también asi:

SELECT
SUM(VALORMTO)
FROM
MOVIMIENTOS
WHERE
HORAMTO >= (SELECT MAX(HORAMTO) FROM MOVIMIENTOS
WHERE IDTIPOMOVIMIENTO = 5 AND FECHAMTO = 'NOW')


Qué es en realidad lo que necesitaba, hacer una suma de todo lo que se ha movido en el día o hasta el momento de cierre de la caja para efectuar un arqueo de lo que se ha vendido, pagado, etc, con el toal que ingresa el usuario al momento de hacer el cierre de caja, que es un módulo en el cual debe insertar todos los valores de monedas que tiene en esta y realizar el arqueo, esa es la idea, espero organizarla para poder implementarla bien.

De todas formas gracias.
:D :D :D

andres1569
12-08-2003, 20:12:00
Bueno, si sabes de antemano la fecha, todo es mucho más fácil. De todas formas ten en cuenta que el arqueo de caja no siempre se va a producir en el mismo día que tuvo la apertura, depende de los horarios de cierre de cada negocio, si cierran más tarde de las 12:00 de la noche, ya estamos en un día diferente. Ya sé que esto no es lo común ni es tu caso, pero es bueno tenerlo en cuenta, como metodología.

Quizás no sea mala idea meter Fecha y Hora en un mismo campo de tipo DateTime, o de tipo TimeStamp, que simplifique los cálculos y comparaciones en las consultas SQL.

Visto lo visto, podrías cambiar el título del hilo, y poner Consulta no tan complicada :D :D

Saludos