如何获取当月和最后两个月之间的所有日期

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已用尽.

Sea*_*nge 5

递归不是一个很好的方法.使用递归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)

  • 唯一的答案(在评论时)不使用rCTE,或者(甚至更糟)一个"WHILE"循环.到目前为止这是正确的答案. (3认同)
  • 很好的答案与理货表的一个很好的例子.感谢您与我们分享这一点. (2认同)