SQL Server 2016:如何用SELECT查询将总量1800拆分为指定批次?
实现总量拆分的SELECT查询方案(SQL Server 2016)
当然可以通过SELECT查询实现这个需求!在SQL Server 2016中,我们可以借助递归CTE或者系统内置的数字表来轻松将总量拆分为指定数量的批次,下面给你两种实用的方案:
方案一:递归CTE生成平均拆分批次
如果希望把总量1800平均拆分为3批(每批600),递归CTE是个直观的选择,它可以动态生成批次号并自动处理总量无法被批次数量整除的情况:
DECLARE @Total INT = 1800; DECLARE @BatchCount INT = 3; DECLARE @BatchSize INT = @Total / @BatchCount; WITH BatchCTE AS ( -- 初始化第一个批次 SELECT BatchNumber = 1, BatchAmount = @BatchSize, RemainingAmount = @Total - @BatchSize UNION ALL -- 递归生成后续批次 SELECT BatchNumber = bc.BatchNumber + 1, BatchAmount = CASE WHEN bc.RemainingAmount > @BatchSize THEN @BatchSize ELSE bc.RemainingAmount END, RemainingAmount = bc.RemainingAmount - CASE WHEN bc.RemainingAmount > @BatchSize THEN @BatchSize ELSE bc.RemainingAmount END FROM BatchCTE bc WHERE bc.RemainingAmount > 0 ) SELECT BatchNumber, BatchAmount FROM BatchCTE OPTION (MAXRECURSION 0); -- 解除递归次数限制(如果批次数量较多)
比如如果总量是1801,这个查询会自动让最后一批为601,其余两批保持600,完美处理余数问题。
方案二:利用系统数字表生成批次
SQL Server的master..spt_values表包含了一组正整数序列,可以用来快速生成指定数量的批次行,代码更简洁:
DECLARE @Total INT = 1800; DECLARE @BatchCount INT = 3; SELECT BatchNumber = number + 1, BatchAmount = CASE WHEN number < @BatchCount - 1 THEN @Total / @BatchCount ELSE @Total - (@Total / @BatchCount) * (@BatchCount - 1) END FROM master..spt_values WHERE type = 'P' -- 筛选出正整数序列 AND number < @BatchCount;
这里通过number列生成0到@BatchCount-1的序列,前@BatchCount-1批取平均数值,最后一批承担所有剩余量(如果有整除余数)。
额外场景:自定义批次大小
如果不需要平均拆分,而是要指定每批的具体数值,直接用VALUES子句构造批次列表即可:
SELECT * FROM ( VALUES (1, 500), (2, 700), (3, 600) ) AS B(BatchNumber, BatchAmount);
内容的提问来源于stack exchange,提问作者Harris
相关产品推荐
相关产品推荐

