创建日期列表,相隔一个月,从当前日期开始

时间:2011-07-05 20:53:34

标签: sql sql-server tsql

我正在寻找一个简单的选择查询(不使用表格)来返回一个相隔1个月的日期列表。输出应该是这样的东西,(假设GetDate()='2011-07-05 11:59:000'我想在NOW()和NOW()+ 4个月之间

Date
2011-07-05 11:59:000
2011-08-05 11:59:000
2011-09-05 11:59:000
2011-10-05 11:59:000
2011-11-05 11:59:000

杀死我的部分是计算明年,例如,如果我在11月份运行此查询,则应将这些月份列为11,12,1,2。谢谢!

9 个答案:

答案 0 :(得分:7)

如果没有修复要求,您可以使用递归CTE并且不需要将UNION串在一起:

 ;with MonthlyCalendar as (
 select cast(getdate() as datetime) as dt
 union all
 select dateadd(mm, 1, dt)
 from MonthlyCalendar
) 
select top 5 dt as [Date] from MonthlyCalendar
option (maxrecursion 0) 

在性能方面,你只需要4个月的时间,UNION远远优于递归选项。

答案 1 :(得分:2)

@ JNK的回答,只是为了给你连续的每一个日期而重新设计:

SELECT GETDATE() 'Date'
UNION
SELECT DATEADD(month, 1, GETDATE()) 'Date'
UNION
SELECT DATEADD(month, 2, GETDATE()) 'Date'
UNION
SELECT DATEADD(month, 3, GETDATE()) 'Date'
UNION
SELECT DATEADD(month, 4, GETDATE()) 'Date'

今天早上不得不做这样的事情!

答案 2 :(得分:2)

我更喜欢通过循环数据并根据当前(或目标)日期构建列表来处理这些小(一次性)情况:

if object_id('tempdb..#dates') is not null drop table #dates
select dateadd(MINUTE, -1, CONVERT(VARCHAR(10), dateadd(DD, 1, getdate()), 111)) result into #dates

declare @current datetime
select @current = result from #dates

while not exists (select * from #dates where result = dateadd(month, 4, @current))
  begin
    insert into #dates
    select dateadd(month, 1, max(result)) from #dates
  end

select * from #dates order by result

答案 3 :(得分:1)

SELECT GETDATE(),
       DATEADD(month, 1, GETDATE()),    
       DATEADD(month, 2, GETDATE()),
       DATEADD(month, 3, GETDATE()),
       DATEADD(month, 4, GETDATE())

DATEADD为你照顾所有那一年的考虑逻辑,并闰年等等。

显然这会返回一列列。请参阅Ryan对行解决方案的回答!

答案 4 :(得分:1)

试试这个:

DECLARE @intFlag INT
declare @LastLimit as int
set @LastLimit = 4
SET @intFlag = 0
WHILE (@intFlag <@LastLimit)
BEGIN
select DATEADD(month, @intFlag, GETDATE())  
SET @intFlag = @intFlag + 1
END

答案 5 :(得分:0)

您可以使用动态脚本来构建日历集 这里有一个很好的例子:
http://blog.namwarrizvi.com/?p=139

在该示例中,您只需将DATEADDDATEDIFF替换为使用月份而非数天。

答案 6 :(得分:0)

这里有一个关于这个问题的通用优雅解决方案:Get usernames logged in on day by day basis from database

当然,这需要调整,但原则很棒。

答案 7 :(得分:0)

在SQL Oracle中,您可以使用CONNECT BY轻松创建日期列表。 例如,如果您想要从2000年12月31日到今天的所有月份:

select add_months(date '2000-12-31',level) dates
from dual 
connect by level <=  months_between(sysdate, date '2000-12-31');

用于获取月数的函数(此处为months_between)可以在不同的SQL版本之间进行更改(例如,在SQL Server中,该日期应为datediff())。

答案 8 :(得分:-1)

保持一个递增值的表格通常很有用,只要你需要它就可以了:

create table sequence ( value int not null primary key clustered )
insert sequence values(0)
insert sequence values(1)
insert sequence values(2)
insert sequence values(3)
. . .
insert sequence values(n)

使用这样的表格,生成任何大小的列表都是微不足道的。这将为您提供36个日期/时间值,相隔一个月,从当前日期/时间开始。

select top 36
       dtValue = dateadd( month , sequence.value , date(current_timestamp) )
from dbo.sequence
order by sequence.value