jueves, 10 de septiembre de 2015

Base de datos

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