我正在寻找一个简单的选择查询(不使用表格)来返回一个相隔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。谢谢!
答案 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
在该示例中,您只需将DATEADD
和DATEDIFF
替换为使用月份而非数天。
答案 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