Sql Calculo de la columna saldo (ayuda)

2,993 views
Skip to first unread message

Gustavo

unread,
Feb 11, 2013, 4:35:10 AM2/11/13
to publice...@googlegroups.com
Hola:

Parece sencillo pero se me esta complicando tengo una tabla caja, con cobros y pagos y quiero añadirle la columna saldo para que se quede asi:

id      cobros   pagos     saldo
1              5          0           5
2             0          3            2

Lo quiero añadir en un grid y estoy creando una consulta pero se queda bloqueado y la memoria se me dispara, me estoy equivocando en algo dejo mi consulta para ver si me podéis ayudar gracias

selec id, cobros, pagos, (selec sum(cobros - pagos) from caja as tmpcaja  where tmpcaja.fecha<= caja.fecha) as saldo from caja

Gracias

Marcos Godoy

unread,
Feb 11, 2013, 6:52:00 AM2/11/13
to publice...@googlegroups.com
Gustavo:

te recomiendo hacerlo en dos pasos



select id,cobros,pagos,0000000.00 as saldo;
 from caja;
 into cursor cr_x readwrite

select cr_x

local vln_saldo

store 0 to vln_saldo

scan
           vln_saldo = vln_saldo + cobros - pagos
           replace saldo with vln_saldo
           
endscan

cuando termina tenes el cursor con los tres campos listos.

Gustavo

unread,
Feb 11, 2013, 7:31:48 AM2/11/13
to publice...@googlegroups.com
Gracias, por tu ayuda. Pero la verdad lo que quiero es hacer con una sentencia sql, yq que estoy intentado evitar los bucles.

Alan Cybar

unread,
Feb 11, 2013, 9:54:22 AM2/11/13
to publice...@googlegroups.com
Gustavo:

Tengo unas preguntas:

Esta es la estructura real de tu tabla?

Es más práctico poner en tablas diferentes los cobros y pagos de las cuotas generadas, ya que se puede dar la posibilidad de que una cuota se pague parcialmente.

entonces podría crear una tabla como esta

idventa       monto     cantcuotas   montocuotas    saldo
1                50.000          5                10.0000      10.0000


y en tabla de cobranzas entonces pones lo siguiente:


idcobranza    idventa    fechacobro        nrocuota    montocuota    montocobrado    saldo
1                       1          11-12-2012          1             10.000             10.000            40.000
2                       1          11-01-2013          2             10.000             10.000           30.0000

Entonces vas actualizando el saldo de tu tabla de ventas.


entonces se hace facil relacionar el cobro con la venta realizada.


Saludos,


Alan

Gustavo

unread,
Feb 11, 2013, 10:06:02 AM2/11/13
to publice...@googlegroups.com
Si la tabla esta ya formada así y no se puede cambiar:
  id_regis, concepto, cobros, pagos

Un saludo y Gracias .

Ricardo Pina

unread,
Feb 11, 2013, 10:52:32 AM2/11/13
to Grupo VFP
Hola Gustavo
 
Cambié el campo fecha por el campo id de la siguiente manera y llegue al resultado con tu ejemplo
 
selec id, cobros, pagos, (selec sum(cobros - pagos) from caja as tmpcaja where tmpcaja.id<= caja.id) as saldo from caja
 
SAludos
--
            

                   Ricardo Pina

Desarrollo y Servicios Informáticos

                  Profesionales
               www.dsip.com.ar

 

 

Pablo Daniel Lissa

unread,
Feb 11, 2013, 11:02:13 AM2/11/13
to publice...@googlegroups.com
Gustavo:

Hola. Tu consulta no tiene error. Simplemente, es pesada. No se me ocurre otra forma de plantearla en una sola sentencia. Me parece que deberías considerar la opción que te propuso Marcos.

Pensémoslo de esta forma:
- en la opción que te propone Marcos, por cada iteración, se realiza una suma de 3 términos: acumulador + cobros - pagos;
- en la expresión SQL, por cada iteración, siendo N el número de iteración, se realiza una suma de 2*N términos. Por ejemplo, si la tabla tuviera 10.000 registros, en la iteración 10.000 estarías sumando 20.000 valores; en la anterior, 19.998; y así sucesivamente.

Saludos.

Ricardo Pina

unread,
Feb 11, 2013, 11:11:34 AM2/11/13
to Grupo VFP
Hola
 
Coincido con Pablo en su razonamiento, con una tabla grande serian esos números, mi prueba fue con 2 registros :-)
y considerando que estabamos hablando de alimentar un Grid asumí otros valores, si es ese el caso lo mejor sería desdoblar el select como ya te indicaron.
 
Saludos

Gustavo

unread,
Feb 12, 2013, 3:43:20 AM2/12/13
to publice...@googlegroups.com

ok. Gracias a todos por la ayuda voy a implementar lo que indica Marcos ya que la prueba que yo hice tarda demasiado.

Gracias.

Claudio Luna

unread,
Feb 12, 2013, 8:39:15 AM2/12/13
to Comunidad de Visual Foxpro en Español
Estimados,
Quizás yo entendí mal el problema pero no se podría resolver más sencillo de esta forma ?
select id,sum(cobros) as cobros ,sum(pagos) as pagos ,sum(cobros-pagos) as saldo from caja group by id 
Saludos
Claudio

Pablo Daniel Lissa

unread,
Feb 12, 2013, 8:49:44 AM2/12/13
to publice...@googlegroups.com
Claudio:

Hola. El problema con esa consulta es que considera el saldo para cada caja por separado (por el GROUP BY id), y Gustavo necesita considerar los cobros y pagos de las cajas anteriores.

Saludos.

Jairo Miranda

unread,
Feb 12, 2013, 3:16:01 AM2/12/13
to publice...@googlegroups.com

Prueba esto:

 

DIMENSION laArray[1]

     

SELECT SUM(detallef.monto) FROM detallef WHERE detallef.id == ?Pedidos.id INTO ARRAY laArray

     

      if !empty(laArray[1])

            thisform.MONTO1.Value = laArray[1]

      else

            thisform..MONTO1.Value = 0

            thisform.MONTO1.Refresh()

      ENDIF

Suma la Columna Monto y deja el resultado en el texbox MONTO1

 

Espero te sirva…

Guillermo MDQ

unread,
Feb 12, 2013, 10:05:52 AM2/12/13
to publice...@googlegroups.com
Se puede tener el saldo acumulado con un SELECT de esta forma:
Pruebenlo a ver que les parece.

CREATE CURSOR CAJA (id I, cobros Y, pagos Y)

INSERT INTO CAJA VALUES (1, 15, 0)
INSERT INTO CAJA VALUES (2, 12, 0)
INSERT INTO CAJA VALUES (3, 0, 10)
INSERT INTO CAJA VALUES (4, 8, 0)
INSERT INTO CAJA VALUES (5, 0, 15)


SELECT A.id, A.cobros, A.pagos,;
      (SELECT SUM(B.cobros-B.Pagos) as saldo FROM CAJA B WHERE b.id<=A.id) ;
      FROM CAJA A



Saludos
Guillermo

Claudio Luna

unread,
Feb 12, 2013, 10:08:58 AM2/12/13
to Comunidad de Visual Foxpro en Español
Guillermo,
Si perfecto así es como lo estaba plantando despues de la observación que me hizo Pablo.
Espero que la solución planteada por vos le sirva a Gustavo.
Saludos
Claudio

Norberto

unread,
Feb 12, 2013, 10:26:53 AM2/12/13
to publice...@googlegroups.com
Sugiero que utilices un periodo (desde fecha-hasta fecha). Luego suma cobros-pagos para fecha < desde y este sería el saldo a principios del periodo. Luego hacer el select solo por este periodo y cambiar la columna saldo con scan endscan tomando el saldo inicial y agregando los movimientos como te sugirio Pablo. Ahora este cursor tendrá solo los registros del periodo. Le haria un append con el saldo inicial y con fecha del dia anterior al comienzo del periodo (id anterior al primero).


El lunes, 11 de febrero de 2013 06:35:10 UTC-3, Gustavo escribió:

Pablo Daniel Lissa

unread,
Feb 12, 2013, 10:29:18 AM2/12/13
to publice...@googlegroups.com
Efectivamente, se puede hacer en una sentencia SELECT. No digo que no se pueda.

Guillermo, tu propuesta es similar a la que hizo Ricardo Pina, y a la que hizo inicialmente Gustavo (que en vez de usar id usa la fecha). Esas sentencias funcionan, pero, el problema es que, ante un gran volumen de datos, la subconsulta se hace pesada.

La propuesta que hizo Marcos Godoy hace uso de un acumulador, y eso evita tener que plantear una sumatoria por cada registro que quiera proyectar con el SELECT.

Saludos.

Claudio Luna

unread,
Feb 12, 2013, 10:36:33 AM2/12/13
to Comunidad de Visual Foxpro en Español
Pablo,
Lo que decis es totalmente cierto , la propuesta de Marcos es la más adecuada para cuando hay muchos registros.
Saludos
Claudio

Guillermo MDQ

unread,
Feb 12, 2013, 10:42:46 AM2/12/13
to publice...@googlegroups.com
Coincido con lo que ustedes dicen, lo que pasa que el amigo que hizo la consulta pidio hacerlo con solo una instruccion Select.
El tendrá que evaluar si le sirve o no de acuerdo a la cantidad de datos que maneje.
Por suerte el zorro nos da muchas formas para obtener el resultado que queremos.

Saludos
Guillermo

Guillermo MDQ

unread,
Feb 12, 2013, 10:48:13 AM2/12/13
to publice...@googlegroups.com
Le pido disculpas a Ricardo Pina porque no habia visto su posteo y al leerlo me di cuenta que la sentencia que puse es la misma solucion  que la que dio el.

Saludos
Guillermo

Ricardo Pina

unread,
Feb 12, 2013, 11:00:39 AM2/12/13
to Grupo VFP
copion :-)

mpulla

unread,
Feb 12, 2013, 11:31:45 PM2/12/13
to publice...@googlegroups.com
Hola Gustavo.

Con el motor de VFP no se puede optimizar tu Sql, si quieres evitar bucles tendrías que cambiarte a un SGDB como Sql Server, My Sql, etc.

Mira estos links te darán una idea de lo que puedes hacer.

http://stackoverflow.com/questions/664700/calculate-a-running-total-in-mysql
http://blogs.solidq.com/ElRinconDelDBA/Post.aspx?ID=205&title=optimiza+con+t-sql+2012+y+cl%C3%A1usula+over

Saludos.
Mauricio

Gustavo

unread,
Feb 13, 2013, 10:57:52 AM2/13/13
to publice...@googlegroups.com
Al final utilice el scan para recalcular el la columna de saldo os dejo mi solución porque haciendo prueba era la mas rápida  teniendo en cuenta que esta una tabla dbf y que la operaciones las realiza terminales:

selec *, 0 as saldo from caja where (condiciones varias) into cursor crsCaja readwrite 

lnAcuSaldo=0
selec crsCaja
scan
  lnSaldo=lnsaldo + crsCaja.cobros - CrsCajaPagos
  replace saldo with lnsado
endscan 

La consulta que propuse al principio tarda mucho mas. Pero bueno, lo de cambiar BD, ya veremos porque actualmente es inviable.

Gracias

Jose Mario

unread,
Feb 27, 2013, 1:45:53 PM2/27/13
to publice...@googlegroups.com
selec *, 0 as saldo from
 lnSaldo=lnsaldo + crsCaja.cobros - CrsCajaPagos
 replace saldo with lnsado

tene cuidado con el campo calculado saldo
deberia de ser asi
0000000.00, si no colo te grabara la logitud 1
Reply all
Reply to author
Forward
0 new messages