Using SQL Server 2008 R2, I have a view, vwBASECustomerTransactions, with a list of transactions, which sum the aggregate data for each transaction type for each day:
Create View vwBASECustomerTransactions AS
Select CustomerID, 0 as TransType, Sum(Amount) as TransAmount, Cast(ChargeDate as Date) as TransDate
from Charge
Group by CustomerID, Cast(ChargeDate as Date)
UNION ALL
Select CustomerID, 1, Sum(Amount), Cast(AdjustDate as Date)
from Adjustment
Group by CustomerID, Cast(AdjustDate as Date)
UNION ALL
Select CustomerID, 2, Sum(Amount), Cast(PaymentDate as Date)
from Payment
Group by CustomerID, Cast(PaymentDate as Date)
The result is:
CustomerID | TransType | TransAmount | TransDate
-----------------------------------------------
120 | 0 | 100 | 1/1/2014
120 | 2 | -100 | 1/1/2014
120 | 0 | 50 | 17/2/2014
There are over 200,000 CustomerIDs and around 2 million Transactions.
I need to find the date where the Balance was the greatest for each CustomerID.
I have created a set of views with a balance calculated at each transaction date, which simply sums the transactions to that point in time, but it is very slow:
--Get the Net Daily Change
Create View vwBASECustomerNetBalChange as
Select CustomerID, TransDate, Sum(TransAmount) as Amount
from vwBASECustomerTransactions
Group by CustomerID, TransDate
--Get the Running Balance for any date
Create View vwRPTCustomerDailyBalance as
Select *, (Select Sum(Amount) from vwBASECustomerNetBalChange Where TransDate <= a.TransDate and CustomerID = a.CustomerID ) as Balance
from vwBASECustomerNetBalChange
--Get the Max Balance for any Customer (join back to get date)
--Takes > 10 minutes to run
Select CustomerID, Max(Balance)
from vwRPTCustomerDailyBalance
group by CustomerID
Is there a better, more efficient way?