I found a faster solution (at least on this small dataset).
;
WITH totals AS (
SELECT *, ABS(Amount) AS Amt, SUM(ABS(Amount)) OVER(PARTITION BY Customer, TransactionType ORDER BY Date ROWS UNBOUNDED PRECEDING ) AS tot
FROM #t1
)
, balances AS (
SELECT *, MIN(CASE WHEN TransactionType = 'Debit' THEN Date END) OVER(PARTITION BY Customer ORDER BY tot, TransactionType ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS PaidDate,
LAG(TransactionType) OVER(PARTITION BY Customer ORDER BY tot, TransactionType) AS PrevTransactionType,
LAG(Date) OVER(PARTITION BY Customer ORDER BY tot, TransactionType) AS PrevDate,
LAG(tot) OVER(PARTITION BY Customer ORDER BY tot, TransactionType) AS PrevTot
FROM totals
)
SELECT TransactionID, Customer,
CASE
WHEN PaidDate IS NOT NULL THEN 0
WHEN PrevTransactionType = 'Credit' THEN Amt
ELSE tot - PrevTot
END AS RemainingBalance,
CASE
WHEN PaidDate IS NOT NULL THEN PaidDate
WHEN PrevTransactionType = 'Debit' THEN PrevDate
END AS LastRedeemedDate
FROM balances
WHERE TransactionType = 'Credit'
ORDER BY tot, TransactionType
If I have the time, I'll run a more complete set.
Drew
J. Drew Allen
Business Intelligence Analyst
Philadelphia, PA