如何在Transact-SQL中实现生成指定和的数字组合函数?
在Transact-SQL中生成指定数量数字和为目标值的所有组合是否可行?
问题描述
需要创建一个Transact-SQL程序(示例中用exec AAA调用,应为存储过程),生成由指定数量的数字组成、和为目标值的所有可能组合。示例如下:
exec AAA 2,10
结果:
1+9 8+2 3+7 4+6 5+5
exec AAA 3,10
结果:
7+2+1 5+2+3 4+5+1
从未在SQL中实现过此类功能,请问是否可行?
回答
可行,这类组合生成问题可以通过**递归CTE(公共表表达式)**在Transact-SQL中实现。以下是具体的存储过程实现:
存储过程代码
CREATE PROCEDURE AAA @NumberCount INT, @TargetSum INT AS BEGIN SET NOCOUNT ON; -- 递归CTE生成非降序组合,避免重复排列 WITH Combinations AS ( -- 基础节点:生成第一个数字的可能取值 SELECT CAST(n AS VARCHAR(MAX)) AS Combination, n AS LastNumber, 1 AS CurrentCount, n AS CurrentSum FROM ( SELECT number FROM master..spt_values WHERE type = 'P' AND number BETWEEN 1 AND @TargetSum - (@NumberCount - 1) ) AS nums(n) UNION ALL -- 递归节点:逐步添加后续数字,保证非降序以避免重复 SELECT c.Combination + '+' + CAST(n AS VARCHAR(MAX)), n, c.CurrentCount + 1, c.CurrentSum + n FROM Combinations c JOIN ( SELECT number FROM master..spt_values WHERE type = 'P' AND number >= 1 ) AS nums(n) ON n >= c.LastNumber AND c.CurrentCount + 1 <= @NumberCount AND c.CurrentSum + n <= @TargetSum ) -- 筛选符合条件的组合 SELECT Combination FROM Combinations WHERE CurrentCount = @NumberCount AND CurrentSum = @TargetSum ORDER BY Combination; -- 可选:按组合字符串排序 END
代码说明
- 递归CTE逻辑:
- 基础部分生成第一个数字的合法范围:第一个数字最小为1,最大为
@TargetSum - (@NumberCount -1)(因为剩余@NumberCount-1个数字至少各为1,总和至少为@NumberCount-1)。 - 递归部分每次添加一个不小于上一个数字的数,确保生成的组合是非降序的,避免了重复排列(比如
1+9和9+1只会生成一次)。
- 基础部分生成第一个数字的合法范围:第一个数字最小为1,最大为
- 筛选条件:最终只保留数字数量等于
@NumberCount且总和等于@TargetSum的组合。
测试结果
执行EXEC AAA 2,10会返回:
1+9 2+8 3+7 4+6 5+5
执行EXEC AAA 3,10会返回完整的组合列表:
1+1+8 1+2+7 1+3+6 1+4+5 2+2+6 2+3+5 2+4+4 3+3+4
如果需要包含所有排列(比如1+9和9+1都显示),只需去掉递归部分的n >= c.LastNumber条件,但这会生成大量重复逻辑的结果,通常这类场景更适合使用非降序的无序组合。
内容的提问来源于stack exchange,提问作者Bookish Mass
相关产品推荐
相关产品推荐

