This is a continuation of my previous question What is the efficient way to generate combination of items in SQL Server? Let me explain the real scenario as what I am looking for and why….
Suppose I have a table as under
Declare @t table(Number Int)
Insert Into @t Values(10),(20),(30),(40),(18)
Number
10
20
30
40
18
and I need to look for a number say 35 (or closest).
Declare @NumberToLookfor = 35
Now the search will happen based on the weight of combination for two pairs. Let me explain.
10+20 = 30
10+30 = 40
10+40 = 50
10+18 = 28
20 + 30 = 50
20 + 40 = 60
20 + 18 = 38
30 + 40 = 70
30 + 18 = 48
40 + 18 = 58
so we can figure out that the weight of any two numbers are teh candidates here e.g. (10,20), (10,30)…(40,18)
Once we get that, the first 3 closest pairs will be (20,18), (10,20) , (10,30) in this case. Because teh dirtance between 35 and 38 (20+18) is 3 whichle it is 5 for the other pairs (10,20) , (10,30).
I think that the explanation is clear to understand what I am looking for.(If not please let me know)
What is the most efficient way of doing so?
My attempt
Declare @t table(Number Int)
Insert Into @t Values(10),(20),(30),(40),(18)
;WITH Cte1 (Number,Ids,TotalWeight) AS
(
SELECT Number
, ',' + CAST(Number AS VARCHAR(MAX))
,CAST(Number AS INT)
FROM @t
UNION ALL
SELECT p.Number
,c.Ids + ',' + CAST(p.Number AS VARCHAR(MAX))
,CAST(c.TotalWeight + p.Number AS INT)
FROM @t AS p JOIN Cte1 c ON p.Number < c.Number
),Cte2 AS(
SELECT
*
,DENSE_RANK() OVER(ORDER BY ABS(TotalWeight - 35)) [rank]
FROM Cte1
WHERE (LEN(Ids) - LEN(REPLACE(Ids, ',', '')))/LEN(',') = 2
)
select *
from Cte2 where [rank] <= 2
It works.

But if the values grows very big say more than 50 or so, then it becomes very very in efficient. Because in the first CTE , I am finding out the full permutation and in the second Cte choosing those values where only two elements participated.
so when the value grows big, the first Cte behaves very very slowly.
Is there any other way of doing so even for big tables.
DDL provided
Declare @t table(Number Int)
Insert Into @t Values
(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15),(16),(17),(18),(19),(20),
(21),(22),(23),(24),(25),(26),(27),(28),(29),(30),(31),(32),(33),(34),(35),(36),(37),(38),(39),(40),
(41),(42),(43),(44),(45),(46),(47),(48),(49),(50),(51),(52),(53),(54),(55),(56),(57),(58),(59),(60),
(61),(62),(63),(64),(65),(66),(67),(68),(69),(70),(71),(72),(73),(74),(75),(76),(77),(78),(79),(80),
(81),(82),(83),(84),(85),(86),(87),(88),(89),(90),(91),(92),(93),(94),(95),(96),(97),(98),(99),(100)
Many thanks in advance
To generically solve for pairs, triplets etc using the brute force method for very small sets, this may work. Update the number in the two indicated locations.