La base de datos utilizada es SQL Server 2014. El modelo E/R
es muy sencillo; se pretende guardar los movimientos que genera el usuario y
poder mostrar el saldo en cada movimiento.
Este es el modelo propuesto.
Un usuario podrá generar N movimientos; los movimientos
tendrán un determinado concepto que a su vez pertenece a un grupo.
Los usuarios tendrán un usuario y contraseña para acceder al
sistema y serán un tipo determinado (Administrador, usuario, …)
Por ejemplo: Un usuario puede insertar un gasto en gasoil
para una fecha determinada y un gasto en un restaurante para esa misma fecha.
Gasoil se podría incluir en el Grupo de Coche y la cena en
el Grupo de Ocio. Es simplemente una agrupación superior de la información para
hacer un estudio general.
CLAUSULA OVER
El saldo se recalcula automáticamente, bien a la hora de
hacer acceder a la aplicación o bien a la hora de insertar un movimiento.
En concepto de cálculo es muy sencillo; habría que recorrer
los movimientos y calcular su saldo, ya que podemos insertar movimientos en
cualquier fecha.
Se podría implementar un procedimiento recursivo que fuera
leyendo los importes de los movimientos anteriores.
Desde la versión de SQL Server 2005 tenemos la posibilidad
de hacer sumas acumulativas utilizando la cláusula OVER con la función SUM
Este es el código que utilizamos en nuestro proyecto:
create procedure dbo.RecalculaSaldo(
@UserName
nvarchar(10))
AS
BEGIN
declare @SaldoInicial decimal(18,2);
Select @SaldoInicial =
SaldoInicial From Users Where UserName = @UserName;
WITH Saldo_CTE (Id,Saldo) as (
--Recalculamos el saldo de cada
movimiento
select Movimientos.id
, @SaldoInicial + sum(importe) over (order by fechamovimiento,id) saldo
from movimientos
WHERE username =@UserName
)
--Actualizamos el saldo de cada
movimiento
Update Movimientos Set
Saldo = Saldo_CTE.Saldo
From Movimientos
inner join Saldo_CTE ON Saldo_CTE.Id = Movimientos.Id
END
Lo que estamos haciendo es filtrar los datos por username y
ordenando por fecha e Id de movimiento. Conseguimos que la función se evalúe
para cada username basándonos en la fecha y el id del movimiento.
La cláusula OVER tiene varios argumentos, pero el que más
uso, junto con order by, es PARTITION, que nos permite particionar la
información por una o varias columnas. En el ejemplo que vemos, no aplica
porque estamos filtrando por username, pero si quisiéramos recalcular el saldo
de todos los movimientos de cada uno de los usuarios, podríamos particionar la
información de esta manera
select Movimientos.id
, sum(importe) over (partition by username
order by
fechamovimiento,id)
saldo
from movimientos
Y obtendríamos una suma acumulativa del saldo de cada
usuario.

No hay comentarios:
Publicar un comentario