New*_*SQL 2 sql t-sql sql-server
我试图在当前月份和最后两个月之间存在所有日期.
例如:今天10-01-2019使用sql脚本,我将获得2018-10-01和2019-01-31之间的所有日期.
with cte as
(
select getdate() as n
union all
select dateadd(DAY,-1,n) from cte where month(dateadd(dd,-1,n)) < month(DATEADD(month, -3, getdate())) --and month(DATEADD(month, 0, getdate()))
union all
select dateadd(DAY,-1,n) from cte where month(dateadd(dd,-1,n)) > month(DATEADD(month, 0, getdate()))
)
select * from cte
Run Code Online (Sandbox Code Playgroud)
我明白了
错误消息530,级别16,状态1,行1语句终止.在语句完成之前,最大递归100已用尽.
递归不是一个很好的方法.使用递归cte递增计数器的性能方面与游标相同.http://www.sqlservercentral.com/articles/T-SQL/74118/
一个更好的方法是基于这个集合.对于此任务,计数表是理想的.这是一篇关于这个主题的精彩文章.
我在我的系统中保留了一个计数表作为视图.零读取时闪电般快速.
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
Run Code Online (Sandbox Code Playgroud)
然后对于类似这个问题的东西,它使用起来非常简单.这将产生相同的结果,没有循环.
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)
Run Code Online (Sandbox Code Playgroud)
- 编辑 -
如果你需要它是动态的,你可以使用一点日期数学.无论您何时运行此数据,这都将从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))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
135 次 |
| 最近记录: |