How to calculate expiring voucher balances in SQL SERVER
Budget: $10 – $30 USD
Hello all
I have a simple table for vouchers that subscribers buy to enable usage minutes on a system
Then a table for usages that were actually used
now, to figure out the balance should be pretty simple with a window function.
Problem is, that some of the vouchers have expiration dates. And for the life of me I can't figure out how to exclude usages after the expiration date. Here is the setup.
CREATE TABLE [dbo].[Vouchers](
[UserID] [int] NOT NULL,
[ID] [int] IDENTITY(1,1) NOT NULL,
[AddedOn] [datetime2](7) NOT NULL,
[Cost] [money] NOT NULL,
[Expiry] [datetime2](7) NULL)
CREATE TABLE [dbo].[Usages](
[Date] [datetime2](7) NOT NULL,
[UserID] [int] NOT NULL,
[Price] [money] NOT NULL,
[ID] [int] IDENTITY(1,1) NOT NULL)
INSERT INTO Vouchers (UserID,AddedOn,Cost,Expiry) Values (1,'2000-01-01',130,NULL)
INSERT INTO Vouchers (UserID,AddedOn,Cost,Expiry) Values (1,'2000-02-01',100,'2000-02-25')
INSERT INTO Usages (UserID,Date,Price) Values (1,'2000-01-02',120)
INSERT INTO Usages (UserID,Date,Price) Values (1,'2000-02-02',70)
INSERT INTO Usages (UserID,Date,Price) Values (1,'2000-02-28',30)
this is the query i use to figure out the minutes left as credit for each user
SELECT *, SUM(Amount) OVER (PARTITION BY userid ORDER BY date ROWS UNBOUNDED PRECEDING) AS Balance
from (
SELECT UserID, AddedOn as Date, Cost as Amount
from vouchers
UNION
SELECT UserID, Date, -Price
FROM Usages)t
can be tested here https://dbfiddle.uk/CjSw5sw5
running this query will show that the user has 10 dollars left. which is wrong. since we are ignoring the fact that the second 100$ already expired before the last usage. hence the user is actually in a minus
how do i write this function correctly?
thanks!
I have a simple table for vouchers that subscribers buy to enable usage minutes on a system
Then a table for usages that were actually used
now, to figure out the balance should be pretty simple with a window function.
Problem is, that some of the vouchers have expiration dates. And for the life of me I can't figure out how to exclude usages after the expiration date. Here is the setup.
CREATE TABLE [dbo].[Vouchers](
[UserID] [int] NOT NULL,
[ID] [int] IDENTITY(1,1) NOT NULL,
[AddedOn] [datetime2](7) NOT NULL,
[Cost] [money] NOT NULL,
[Expiry] [datetime2](7) NULL)
CREATE TABLE [dbo].[Usages](
[Date] [datetime2](7) NOT NULL,
[UserID] [int] NOT NULL,
[Price] [money] NOT NULL,
[ID] [int] IDENTITY(1,1) NOT NULL)
INSERT INTO Vouchers (UserID,AddedOn,Cost,Expiry) Values (1,'2000-01-01',130,NULL)
INSERT INTO Vouchers (UserID,AddedOn,Cost,Expiry) Values (1,'2000-02-01',100,'2000-02-25')
INSERT INTO Usages (UserID,Date,Price) Values (1,'2000-01-02',120)
INSERT INTO Usages (UserID,Date,Price) Values (1,'2000-02-02',70)
INSERT INTO Usages (UserID,Date,Price) Values (1,'2000-02-28',30)
this is the query i use to figure out the minutes left as credit for each user
SELECT *, SUM(Amount) OVER (PARTITION BY userid ORDER BY date ROWS UNBOUNDED PRECEDING) AS Balance
from (
SELECT UserID, AddedOn as Date, Cost as Amount
from vouchers
UNION
SELECT UserID, Date, -Price
FROM Usages)t
can be tested here https://dbfiddle.uk/CjSw5sw5
running this query will show that the user has 10 dollars left. which is wrong. since we are ignoring the fact that the second 100$ already expired before the last usage. hence the user is actually in a minus
how do i write this function correctly?
thanks!