Sql server 将日期添加到表的SQL循环无效
我有一个WHILE循环,应该循环30次,但出于某种原因,它似乎只循环15次 SQL: 当我尝试将DATEDIFF(d、@dateInsert、@dateLoopTo)更改为30时,SQL似乎可以工作Sql server 将日期添加到表的SQL循环无效,sql-server,tsql,while-loop,Sql Server,Tsql,While Loop,我有一个WHILE循环,应该循环30次,但出于某种原因,它似乎只循环15次 SQL: 当我尝试将DATEDIFF(d、@dateInsert、@dateLoopTo)更改为30时,SQL似乎可以工作 WHILE @cnt <= 30-- DATEDIFF (d, @dateInsert , @dateLoopTo ) 而@cnt在循环的每一步,您都在增加cnt和@DateInsert。因此,您正在通过2 如何将代码写得更清楚,如下所示: WHILE @cnt <= 30 而@cn
WHILE @cnt <= 30-- DATEDIFF (d, @dateInsert , @dateLoopTo )
而@cnt在循环的每一步,您都在增加cnt
和@DateInsert
。因此,您正在通过2
如何将代码写得更清楚,如下所示:
WHILE @cnt <= 30
而@cnt在循环的每一步,您都在增加cnt
和@DateInsert
。因此,您正在通过2
如何将代码写得更清楚,如下所示:
WHILE @cnt <= 30
当@cnt时,您递增cnt
并递减DATEDIFF
(在循环内部递增@dateInsert
会导致递减差异)同时:
First iteration: cnt = 0; DATEDIFF(d, @dateInsert , @dateLoopTo ) = 30
Second iteration: cnt = 1; DATEDIFF = 29
Third iteration: cnt = 2; DATEDIFF = 28
..
15th iteration: cnt = 15; DATEDIFF = 15
避免这种情况的一种方法是使用固定值:
WHILE @cnt <= 30
当@cnt时,您递增cnt
并递减DATEDIFF
(在循环内部递增@dateInsert
会导致递减差异)同时:
First iteration: cnt = 0; DATEDIFF(d, @dateInsert , @dateLoopTo ) = 30
Second iteration: cnt = 1; DATEDIFF = 29
Third iteration: cnt = 2; DATEDIFF = 28
..
15th iteration: cnt = 15; DATEDIFF = 15
避免这种情况的一种方法是使用固定值:
WHILE @cnt <= 30
WHILE@cnt您可以使用基于集合的方法来实现这一点,这是我建议尽可能多地使用循环的方法。要列出两个日期之间的所有日期,可以执行以下操作:
DECLARE @dateInsert date
DECLARE @dateLoopTo date
SET @dateInsert='2016-01-01'
SET @dateLoopTo='2016-01-31'
SELECT DATEADD(dd, Number, @dateInsert)
FROM
(
SELECT TOP (DATEDIFF(dd, @dateInsert, @dateLoopTo))
ROW_NUMBER() OVER (ORDER BY o.object_id) - 1 AS Number
FROM sys.objects o
CROSS JOIN sys.objects o2
) x
如果这是一项常见的活动,我建议在数据库中创建一个数字表(单列,用1到x的数字填充一次,其中x=大约需要数字的高度加上一点额外的数字)。同样,根据用例/场景的不同,您还可以创建一个“日期”表并进行预填充-这基本上消除了每次计算日期范围的需要。您可以使用基于集合的方法来实现这一点,这是我建议尽可能多地使用循环的方法。要列出两个日期之间的所有日期,可以执行以下操作:
DECLARE @dateInsert date
DECLARE @dateLoopTo date
SET @dateInsert='2016-01-01'
SET @dateLoopTo='2016-01-31'
SELECT DATEADD(dd, Number, @dateInsert)
FROM
(
SELECT TOP (DATEDIFF(dd, @dateInsert, @dateLoopTo))
ROW_NUMBER() OVER (ORDER BY o.object_id) - 1 AS Number
FROM sys.objects o
CROSS JOIN sys.objects o2
) x
DECLARE @dateInsert date
DECLARE @dateLoopTo date
如果这是一项常见的活动,我建议在数据库中创建一个数字表(单列,用1到x的数字填充一次,其中x=大约需要数字的高度加上一点额外的数字)。同样,根据用例/场景的不同,您还可以创建一个“日期”表并进行预填充-这基本上消除了每次计算日期范围的需要
DECLARE @dateInsert date
DECLARE @dateLoopTo date
声明计数变量并在while条件中使用
DECLARE @cnt INT = 0;
SET @dateInsert='2016-01-01'
SET @dateLoopTo='2016-01-31'
DECLARE @Count INT =DATEDIFF (d, @dateInsert , @dateLoopTo )
WHILE @cnt <= @Count
BEGIN
print CONVERT(VARCHAR(10),@dateInsert) + ' '+ CONVERT(VARCHAR(2),@cnt)
SET @dateInsert = DATEADD(d, 1,@dateInsert)
SET @cnt = @cnt + 1;
END
DECLARE@cnt INT=0;
设置@dateInsert='2016-01-01'
将@dateLoopTo='2016-01-31'
声明@Count INT=DATEDIFF(d、@dateInsert、@dateLoopTo)
而@cnt
声明计数变量并在while条件中使用
DECLARE @cnt INT = 0;
SET @dateInsert='2016-01-01'
SET @dateLoopTo='2016-01-31'
DECLARE @Count INT =DATEDIFF (d, @dateInsert , @dateLoopTo )
WHILE @cnt <= @Count
BEGIN
print CONVERT(VARCHAR(10),@dateInsert) + ' '+ CONVERT(VARCHAR(2),@cnt)
SET @dateInsert = DATEADD(d, 1,@dateInsert)
SET @cnt = @cnt + 1;
END
DECLARE@cnt INT=0;
设置@dateInsert='2016-01-01'
将@dateLoopTo='2016-01-31'
声明@Count INT=DATEDIFF(d、@dateInsert、@dateLoopTo)
虽然@cnt这不是一个答案(因为@Gordon Linoff
已经提供了一个答案),但这是一种无需使用WHILE loop
、使用更多本机查询即可实现所需的方法。此变体与@AdaTheDev
答案类似,但不使用sys表(可能是您对使用它们有限制)
这里是使用递归cte的变量
这不是一个答案(因为@Gordon Linoff
已经提供了一个答案),而是一种不使用WHILE loop
,使用更多本地查询来实现所需的方法。此变体与@AdaTheDev
答案类似,但不使用sys表(可能是您对使用它们有限制)
这里是使用递归cte的变量
由于在循环中更改了dateInsert
,我看不出DATEDIFF(d,@dateInsert,@dateLoopTo)
在第一次迭代后仍然返回30。由于在循环中更改了dateInsert
,我看不到DATEDIFF(d,@dateInsert,@dateLoopTo)
在第一次迭代后仍将返回30。请注意此处。您正在使用cte进行计数,看起来它是基于集合的,但实际上它与巧妙隐藏的循环是一样的。这里要小心。您正在使用cte进行计数,看起来它是基于集合的,但实际上它与巧妙隐藏的循环是一样的。