我有一组这样的数据:
MinNo: 2500
MaxNo: 2700
IncrementStep: 10
在最小数量和最大数量之间,列出具有给定步骤的所有可能数字的列表,如下所示:
2500
2510
2520
2530
2540
2550
2560
2570
2580
2590
2600
2610
2620
2630
2640
2650
2660
2670
2680
2690
2700
我知道这可以使用while循环来实现。如果可以使用Common Table Expressions(如果需要)使用select查询来完成此操作,请告诉我。提前谢谢。
答案 0 :(得分:4)
您可以使用数字表(或master..spt_values)。
declare @MinNo int
declare @MaxNo int
declare @IncrementStep int
set @MinNo = 2500
set @MaxNo = 2700
set @IncrementStep = 10
select @MinNo + Number * @IncrementStep
from master..spt_values
where type = 'P' and
number between 0 and (@MaxNo - @MinNo) / @IncrementStep
或递归CTE
;with C as
(
select @MinNo as Num
union all
select Num + @IncrementStep
from C
where Num < @MaxNo
)
select Num
from C
答案 1 :(得分:1)
查看此有用功能
CREATE FUNCTION [dbo].[Sequence](@min INT, @max INT, @step INT)
RETURNS @ret TABLE (id INT PRIMARY KEY)
AS
BEGIN
WITH numbers(id) as
(
SELECT @min id
UNION ALL
SELECT id+@step
FROM numbers
WHERE id < @max
)
INSERT @ret
SELECT id FROM Numbers
OPTION(MAXRECURSION 0)
RETURN
END
答案 2 :(得分:1)
我只是想分享一下我前几天在网上看到的一个非递归的基于CTE的“计数表”解决方案,我觉得它的大范围(4亿个逻辑行)非常优雅,并且没有任何一般的适用性数据库依赖:
WITH
E00(N) AS (SELECT 1 UNION ALL SELECT 1),
E02(N) AS (SELECT 1 FROM E00 a, E00 b),
E04(N) AS (SELECT 1 FROM E02 a, E02 b),
E08(N) AS (SELECT 1 FROM E04 a, E04 b),
E16(N) AS (SELECT 1 FROM E08 a, E08 b),
E32(N) AS (SELECT 1 FROM E16 a, E16 b),
cteTally(N) AS (SELECT ROW_NUMBER() OVER (ORDER BY N) FROM E32)
SELECT *
FROM cteTally
WHERE N >= 2500
AND N <= 2700
AND N % 10 = 0
我发现它here,但我不知道这是否是此CTE的原始来源。
关于它的好处是你不需要担心最小值,最大值或步长,但它在大多数(一次性)情况下表现非常好。也就是说,它不应该用于任何经常被称为业务流程;任何物理索引号码表总是会表现得更好!
编辑:我刚刚搜索了一下这个方法的来源(我错过了我引用的文章中的stackoverflow链接),显然它最初归因于Itzik Ben-Gan,来自255页的底部标题为“内部Microsoft SQL Server 2005 - T-SQL查询”的书(says Jeff Moden,我暗中信任)。