duda respecto a sumar y restar dentro de un cursor ??

713 views
Skip to first unread message

Saul Piña Hernandez

unread,
Jan 20, 2016, 7:23:35 PM1/20/16
to Comunidad de Visual Foxpro en Español
Saludos, 

de nuevo aqui con una duda que tengo.  Pues sucede que no habia percatado que me hacia falta realizar un calculo mas a esta consulta, pero al intentar agregar una resta ya no me da el resultado deseado.

dejo el codigo:

select departamentos.id, departamentos.departamento,
ventas
.idCliente, clientes.nombre,
sum
(ventas_movimientos.importe)-sum(cobranzas.importe) as saldo
from ventas_movimientos
inner join ventas
    on ventas_movimientos
.idventa = ventas.id
inner join clientes
    on ventas
.idCliente = Clientes.id
inner join cobranzas
    on cobranzas
.idCliente = Clientes.id    
inner join departamentos
    on clientes
.idDepartamento = Departamentos.id

 
group by ventas.idcliente
 order
by Departamentos.departamento        

-- where fecha>='2016-01-16' and fecha<='2016-01-19'

Lo que intento es que la columna saldo sea la deuda real del cliente, tomando en cuenta que se debe primeramente sumar todas las compras de ventas_movimientos.importe segun el cliente e inmediatamente restar del resultado de la suma de cobranzas.importe segun el cliente...

sum(ventas_movimientos.importe)-sum(cobranzas.importe) as saldo


Lo que me arroja un resultado nulo.

Alguna sugerencia?

muchas gracias..

el problema está en esta linea:


Elkin Fernando Ortiz

unread,
Jan 20, 2016, 8:36:53 PM1/20/16
to publice...@googlegroups.com

En mi opinión,le pondría la intersección entre ventas y cobranzas con el campo idcliente, en el inner join de cobranzas.

Saludos

Víctor Hugo Espínola Domínguez

unread,
Jan 20, 2016, 9:43:32 PM1/20/16
to publice...@googlegroups.com
Hola Saúl

No aclaras si la consulta es para ser enviada desde VFP o es parte de un SP en algún SGBD.

Hago la suposición de que lo quieres en VFP, en primer lugar mejoramos la legibilidad de la consulta mediante el uso de alias y sangrías:

Local lcSelect As String
Text To m.lcSelect Textmerge Noshow Pretext 15

  Select  dep.Id
          , dep.departamento
  , vta.idCliente
  , cli.nombre
  , Sum(mov.importe) - Sum(cob.importe) As saldo
From ventas_movimientos As mov
Inner Join ventas As vta
On mov.idventa = vta.Id
Inner Join clientes As cli
On vta.idCliente = cli.Id
Inner Join cobranzas
On cob.idCliente = cli.Id
Inner Join departamentos As dep
On cli.idDepartamento = dep.Id
Group By vta.idCliente
Order By dep.departamento

Endtext

Creo que se  nota que este código es más legible, ahora mis acotaciones:

1) La lista de columnas entre SELECT y SUM  no coincide con la lista después de GROUP BY.
SYNTAX

The syntax for the GROUP BY clause in MySQL is:

SELECT expression1, expression2, ... expression_n, 
       aggregate_function (expression)
FROM tables
[WHERE conditions]
GROUP BY expression1, expression2, ... expression_n;
http://www.techonthenet.com/mysql/group_by.php

2) Sum(mov.importe) - Sum(cob.importe), si un movimiento de venta no tiene su correspondiente importe de cobranza entonces cob.importe será NULL y la suma también. Para prevenir esto se usa la función NVL de VFP o COALESCE de los SGBD, creo que usas MySql, entones la expresión debe ser: Sum(Coalesce(mov.importe, 0)) - Sum(Coalesce(cob.importe), 0)

3) Inner Join cobranzas On cob.idCliente = cli.Id, si un movimiento de venta no tiene su correspondiente importe de cobranza entonces el saldo de esa venta no aparecerá en el resultado de la consulta. Cambia INNER por LEFT.


Saludos,
Víctor.
Lambaré - Paraguay.

Antonio Meza

unread,
Jan 20, 2016, 9:53:38 PM1/20/16
to Comunidad de Visual Foxpro en Español
Hola Saul  !!!

Prueba a ver si te funciona así, es mejor SUM(a - b) que Sum(a) - Sum(b) y otro detalle no todas las ventas tienen cobranza o no todos los clientes te han pagado, es mejor usar LEFT que INNER. 

select
  departamentos
.id
 
, departamentos.departamento
 
, ventas.idCliente
 
, clientes.nombre
 
, sum(ventas_movimientos.importe - ISNULL(cobranzas.importe,0)) as saldo
 
from ventas_movimientos

 inner join ventas
    on ventas_movimientos
.idventa = ventas.id

 inner join clientes
    on ventas
.idCliente = Clientes.id

 inner join departamentos
     on clientes
.idDepartamento = Departamentos.id
 left join cobranzas
    on cobranzas
.idCliente = Clientes.id    
 
group by ventas.idcliente
 order
by Departamentos.departamento        
 
where fecha>='2016-01-16' and fecha<='2016-01-19'


Nota: No hay como probar con datos para estar seguros que funciones, así que algo puede fallar jajaja


Suerte!!

saludos
Antonio Meza

Antonio Meza

unread,
Jan 20, 2016, 10:28:18 PM1/20/16
to Comunidad de Visual Foxpro en Español
Al ponerle que mostrara código destrozo el select jajajaj a ver si así se ve mejor

select 
, departamentos.departamento
, ventas.idCliente
, clientes.nombre
, sum(ventas_movimientos.importe - ISNULL(cobranzas.importe,0)) as saldo
from ventas_movimientos
inner join ventas 
on ventas_movimientos.idventa = ventas.id
  inner join clientes 
  on ventas.idCliente = Clientes.id
inner join departamentos
on clientes.idDepartamento = Departamentos.id
  left join cobranzas
    on cobranzas.idCliente = Clientes.id    
group by ventas.idcliente
order by Departamentos.departamento        
where fecha>='2016-01-16' and fecha<='2016-01-19'

saludos
Antonio Meza

Víctor Hugo Espínola Domínguez

unread,
Jan 20, 2016, 10:31:33 PM1/20/16
to publice...@googlegroups.com
Hola Antonio

En vez de ISNULL(cobranzas.importe,0) debe ser NVL(cobranzas.importe,0) para VFP o COALESCE(cobranzas.importe,0) para MySql.


Saludos,
Víctor.
Lambaré - Paraguay.


Antonio Meza

unread,
Jan 20, 2016, 11:24:34 PM1/20/16
to Comunidad de Visual Foxpro en Español
Por cierto es IFNULL() no ISNULL() así que Saul cambia el nombre jajaja

IFNULL() es solo para Mysql o MariaDB,

ISNULL es para SqlServer y creo que para firebird no estoy seguro.

Conclusión:

IFNULL() remplaza un valor NULL por el valor que se indique, ejemplo:
Select IFNULL(Null,1)
Select IFNULL(Null,"Vacio")

COALESCE es un estándar SQL, devuelve el primera expresión no Null entre sus argumentos, es decir permite indicarle mas argumentos, ejemplo:
Select COALESCE(null, null, null, null, 1)
Select COALESCE((Null,1)

Cada una tiene sus ventajas y desventajas, por ejemplo para números y si solo se requiere comparar una expresión es mas fácil de recordar  IFNULL() si es para caracteres es mejor COALESCE, porque IFNULL() con cadenas tomara el tamaño de caracteres de la primera cadena, es decir tenemos un campo varchar(20) y si el primer registro tiene solo 5 caracteres, "ABCDE" IFNULL devuelve "ABCDE", pero para los siguientes registros sin importar cuantos caracteres tengan siempre devolverá los 5 primeros es decir recorta la longitud del campo según los caracteres que contenga el primer registro, en cambio eso no sucede con COALESCE que siempre retornara los caracteres que contenga cada registro

saludos
Antonio Meza

Víctor Hugo Espínola Domínguez

unread,
Jan 20, 2016, 11:31:32 PM1/20/16
to publice...@googlegroups.com
👍

Saludos,
Víctor.
Lambaré - Paraguay.


Saul Piña Hernandez

unread,
Jan 21, 2016, 9:29:15 AM1/21/16
to Comunidad de Visual Foxpro en Español
Buenos dias Genios,

lo voy a probar, viniendo de ustedes, seguro se tiene un buen resultado...gracias
Reply all
Reply to author
Forward
0 new messages