SQL Server如何获取NumberPageMax总和接近50的随机文档列表
SQL Server 文档抽取需求实现方案
该需求可以通过SQL实现,属于子集和问题的轻量化场景,借助递归CTE即可完成,不需要额外的程序处理。
实现逻辑
- 用递归CTE遍历所有不重复的文档组合,计算每个组合的总页数,限制组合总页数不超过「50+单文档最大页数」,避免生成无意义的超大组合
- 筛选出总页数≥50的所有合法组合,按总页数升序排序,优先保留总页数最小的组合(刚好等于50的组合会排在最前,无匹配时自动取最接近的略高值)
- 对符合条件的最小总页数组合做随机排序,取1组返回即可
完整实现代码
假设你的文档表名为DocumentInfo,代码如下:
WITH RecursiveCombination AS ( -- 锚点成员:单个文档作为初始组合 SELECT CAST(Document AS NVARCHAR(MAX)) AS SelectedDocumentList, NumberPageMax AS TotalPage, Document AS LastSelectedDoc FROM DocumentInfo WHERE NumberPageMax <= 50 + (SELECT MAX(NumberPageMax) FROM DocumentInfo) UNION ALL -- 递归成员:拼接新文档,通过字典序避免重复组合 SELECT CAST(CONCAT(c.SelectedDocumentList, ',', d.Document) AS NVARCHAR(MAX)), c.TotalPage + d.NumberPageMax, d.Document FROM RecursiveCombination c INNER JOIN DocumentInfo d ON d.Document > c.LastSelectedDoc -- 保证每个文档仅被选择一次,避免重复生成相同组合 WHERE c.TotalPage + d.NumberPageMax <= 50 + (SELECT MAX(NumberPageMax) FROM DocumentInfo) ), ValidCombination AS ( SELECT SelectedDocumentList, TotalPage, -- 排序规则:先按总页数升序,再随机排序 ROW_NUMBER() OVER(ORDER BY TotalPage ASC, NEWID()) AS RankNum FROM RecursiveCombination WHERE TotalPage >= 50 ) -- 取排名第一的随机合法组合 SELECT SelectedDocumentList, TotalPage FROM ValidCombination WHERE RankNum = 1
代码说明
- 递归逻辑中通过
d.Document > c.LastSelectedDoc的限制,保证同一个组合只会生成一次,比如不会同时出现First,Sixth和Sixth,First,大幅降低计算量 NEWID()是SQL Server的随机生成函数,保证每次执行都会随机返回一个合法组合- 若存在总页数刚好等于50的组合,会优先返回该类组合,没有匹配时自动返回总页数最小的略高于50的组合
- 针对示例数据执行时,会优先返回总页数为51的组合,比如
First,Sixth
性能提示
如果你的文档表数据量超过20条,建议在递归逻辑中增加组合包含文档数量的上限限制,避免递归层级过高导致性能下降。
内容的提问来源于stack exchange,提问作者Melissa
相关产品推荐
相关产品推荐

