这是我之前的问题的延续在 SQL Server 中生成项目组合的有效方法是什么?让我解释一下我正在寻找的真实场景以及为什么....
假设我有一张桌子如下
Declare @t table(Number Int)
Insert Into @t Values(10),(20),(30),(40),(18)
Number
10
20
30
40
18
我需要寻找一个数字,比如 35(或最接近)。
Declare @NumberToLookfor = 35
现在将根据两对组合的权重进行搜索。让我解释。
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
所以我们可以计算出任何两个数字的权重都是候选者,例如 (10,20), (10,30)...(40,18)
一旦我们得到它,在这种情况下,前 3 个最接近的对将是 (20,18), (10,20) , (10,30)。因为 35 和 38 (20+18) 之间的污垢是 3,而其他对 (10,20) 和 (10,30) 的污垢是 5。
我认为解释很清楚,可以理解我在寻找什么。(如果没有,请告诉我)
这样做最有效的方法是什么?
我的尝试
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
有用。
但是,如果值变得非常大,例如超过 50 左右,那么它变得非常非常有效。因为在第一个 CTE 中,我找出了完整的排列,而在第二个 CTE 中,我选择了只有两个元素参与的那些值。
所以当值变大时,第一个 Cte 的行为非常非常缓慢。
即使对于大桌子,还有其他方法吗?
提供 DDL
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)
提前谢谢了