递归不是解决这个问题的好方法。使用递归 cte 来增加计数器的性能与游标相同。 http://www.sqlservercentral.com/articles/T-SQL/74118/
更好的方法是基于这个集合。对于这项任务,一个计数表是理想的。 Here 是一篇关于该主题的精彩文章。
我在系统中保留了一个计数表作为视图。零读取速度快如闪电。
create View [dbo].[cteTally] as
WITH
E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
cteTally(N) AS
(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
)
select N from cteTally
GO
然后对于像这个问题它是超级简单的使用。这将产生相同的结果,没有循环。
declare @endDate datetime = '2019-01-31'
, @tmpDate datetime = '2018-10-01'
select dateadd(day, t.N - 1, @tmpDate)
from cteTally t
where t.N - 1 <= DATEDIFF(day, @tmpDate, @endDate)
--编辑--
如果您需要它是动态的,您可以使用一点日期数学。这将获取从 3 个月前开始到当月月底的数据,无论您何时运行它。如果您以前没有见过这种东西,日期逻辑可能有点难以破译。 Lynn Pettis 有一篇关于这个主题的精彩文章。 http://www.sqlservercentral.com/blogs/lynnpettis/2009/03/25/some-common-date-routines/
select dateadd(day, t.N - 1, dateadd(month, -3, dateadd(month, datediff(month, 0, getdate()), 0)))
from cteTally t
where t.N - 1 < datediff(day,dateadd(month, -3, dateadd(month, datediff(month, 0, getdate()), 0)), dateadd(month, datediff(month, 0, getdate()) + 1, 0))