In SQL Server, I have a Transactions and a TransactionDetails table.
Transactions table has the following columns:
TransactionId
Amount
ProcessedDate
TransactionDetailsId
TransactionDetails table has following columns:
TransactionDetailsId
AdvanceId
I have initial values for ClearedBalance and PendingBalance.
I need to write a query to select from Transactions table starting from specific transaction to all transactions down which has ProcessedDate greater than starting transaction. This query should also calculate running balances for each transaction.
I chose to to it using this recursive CTE:
-- Here we get current balances for advance
DECLARE @InitialPendingBalance DECIMAL(18, 2) = 1000000;
DECLARE @InitialClearedBalance DECIMAL(18, 2) = 1000000;
WITH RecursiveBalances AS
(
-- Base case: Start with the new transaction
SELECT
t.TransactionId,
td.AdvanceId,
t.Amount,
CAST(@InitialPendingBalance + t.Amount AS DECIMAL(18, 2)) AS PendingBalance,
CAST(@InitialClearedBalance + t.Amount AS DECIMAL(18, 2)) AS ClearedBalance,
t.ProcessedDate
FROM
[transaction].Transactions t
JOIN
[transaction].TransactionDetails td ON t.TransactionDetailsId = td.TransactionDetailId
WHERE
t.TransactionId = 8743
UNION ALL
-- Recursion part
SELECT
t.TransactionId,
td.AdvanceId,
t.Amount,
CAST(rb.PendingBalance + t.Amount AS DECIMAL(18, 2)) AS PendingBalance,
CAST(rb.ClearedBalance + t.Amount AS DECIMAL(18, 2)) AS ClearedBalance,
t.ProcessedDate
FROM
[transaction].Transactions t
JOIN
[transaction].TransactionDetails td ON t.TransactionDetailsId = td.TransactionDetailId
AND td.AdvanceId = 100000800
JOIN
RecursiveBalances rb ON t.ProcessedDate > rb.ProcessedDate
)
SELECT
TransactionId,
COUNT(*)
FROM
RecursiveBalances
GROUP BY
TransactionId
ORDER BY
COUNT(*);
This CTE returns starting transaction and transactions happened after this transaction but it contains duplicates. Number of duplicates increases exponentially.
select
TransactionId,
count(*)
from RecursiveBalances
group by TransactionId
order by count(*)
this query returns this result:
| TransactionId | Count |
|---|---|
| 8743 | 1 |
| 8744 | 1 |
| 8767 | 2 |
| 8777 | 2 |
| 8783 | 6 |
| 8789 | 12 |
| 8794 | 12 |
| 8799 | 36 |
| 8803 | 36 |
| 8809 | 108 |
| 8813 | 108 |
How can I solve this duplication issue?
CREATE TABLE ...statement), example data, expected result and current result.JOIN RecursiveBalances rb ON t.ProcessedDate > rb.ProcessedDatematches every row with a previous date, whether it's related or not. You don't need a recursive CTE to create a running total anyway. You can useCOUNT(*) OVER(PARTITION BY TransactionID ORDER BY ProcessedDate)OVER(PARTITION BY ...ORDER BY ...)clause is for. You can use that with aggregation functions likeSUM,COUNTetc.