I found examples online using a recursive CTE to find all combinations of values that equal one target amount. The database column ledger_amount is DECIMAL(26,6).
DECLARE @TARGET_AMOUNT DECIMAL(26, 6) = 15.02;
IF (OBJECT_ID('tempdb..#Temp_Ledger_Amounts') IS NOT NULL)
DROP TABLE #Temp_Ledger_Amounts;
CREATE TABLE #Temp_Ledger_Amounts (
[transaction_id] [bigint] IDENTITY(1, 1) NOT NULL
, [ledger_amount] [decimal](26, 6) NOT NULL
);
INSERT INTO #Temp_Ledger_Amounts (ledger_amount)
VALUES (17.38)
, (12.11)
, (1.34)
, (7.31)
, (8.93)
, (6.99)
, (8.03);
WITH CombinationsCTE (
CombinationString
, CurrentSum
, LastID
)
AS (
-- Anchor member: Start with each individual number
SELECT CAST(ledger_amount AS NVARCHAR(MAX))
, ledger_amount
, transaction_id
FROM #Temp_Ledger_Amounts
WHERE ledger_amount <= @TARGET_AMOUNT
UNION ALL
-- Recursive member: Add numbers to existing combinations
SELECT c.CombinationString + ', ' + CAST(n.ledger_amount AS NVARCHAR(MAX))
, c.CurrentSum + n.ledger_amount
, n.transaction_id
FROM CombinationsCTE c
-- Ensure unique combinations
JOIN #Temp_Ledger_Amounts n ON n.transaction_id > c.LastID
WHERE c.CurrentSum + n.ledger_amount <= @TARGET_AMOUNT
)
SELECT CombinationString
, CurrentSum
FROM CombinationsCTE
WHERE CurrentSum = @TARGET_AMOUNT
ORDER BY CombinationString;
The error I get is:
Types don't match between the anchor and the recursive part in column "CurrentSum" of recursive query "CombinationsCTE".
c.CurrentSum + n.ledger_amountis not of typeDECIMAL(26,6)as you try to assign it. You could try to cast it asCAST(c.CurrentSum + n.ledger_amount AS DECIMAL(26,6)). But that's just guessing.', 'isn't unicode, where asN', 'is unicode. As the string is just numerals, decimals, spaces and commas, there's no need for unicode at all.ledger_amountthis is going to run forever. As an example, a transaction table with 100 records, an averageledger_amountof1700, standard deviation of875andtarget_amountof3400will produce hundreds of thousands of combinations for the final query to filter. I'm guessing your table is much bigger, and that yourtarget_amountis significantly larger than your average. You may be waiting for the heat death of the universe for this return.