简体   繁体   English

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

[英]Create list of dates, a month apart, starting from current date

I'm looking for a simple select query (not using a table) to just return a list of dates, 1 month apart.我正在寻找一个简单的 select 查询(不使用表格)来仅返回相隔 1 个月的日期列表。 The output should looke something like this, (assuming GetDate() = '2011-07-05 11:59:000' and I wanted between NOW() and NOW()+4 months output 应该看起来像这样,(假设 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

The part that's killing me is calculating the next year, for example if i run this query in Nov, the months should be listed as 11, 12, 1, 2. Thanks!杀死我的部分是计算明年,例如,如果我在 11 月运行此查询,月份应列为 11、12、1、2。谢谢!

You can use recursive CTE and need not string UNIONs together if the requirement is not fixed as below:如果要求不固定,您可以使用递归 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) 

When it comes to performance and you have the need for only 4 months above UNION is far superior than recursive option.在性能方面,你只需要 4 个月以上的 UNION 远远优于递归选项。

I prefer to handle these small (one off) situations by looping through the data and building the list based on the current (or target) date:我更喜欢通过循环数据并根据当前(或目标)日期构建列表来处理这些小(一次性)情况:

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

@JNK's answer, just reworked to give you each date in a row: @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'

Had to do something like this just this morning!就在今天早上不得不做这样的事情!

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

DATEADD takes care of all that year consideration logic for you, and leap years and such too. DATEADD为您处理所有年份考虑逻辑,以及闰年等。

Obviously this returns a list of columns.显然,这会返回一个列列表。 See Ryan's answer for the row solution!请参阅 Ryan 对行解决方案的回答!

try this:尝试这个:

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

In SQL Oracle, you can easily create a list of dates using CONNECT BY.在 SQL Oracle 中,您可以使用 CONNECT BY 轻松创建日期列表。 For example, if you want all the months between '2000-12-31' and today:例如,如果您想要 '2000-12-31' 和今天之间的所有月份:

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

The function used to obtain the number of months, here months_between , can change between different SQL versions (eg in SQL Server it should be datediff() ). function 用于获取月数,这里months_between ,可以在不同的 SQL 版本之间更改(例如在 SQL 服务器中应该是datediff() )。

You can use a dynamic script to build a calendar set.您可以使用动态脚本来构建日历集。
A good example can be found here:一个很好的例子可以在这里找到:
http://blog.namwarrizvi.com/?p=139 http://blog.namwarrizvi.com/?p=139

In that example you would just replaced the DATEADD and DATEDIFF to use months instead of days.在该示例中,您只需将DATEADDDATEDIFF替换为使用月而不是天。

There is a generic elegant solution on the problem here: Get usernames logged in on day by day basis from database这里有一个通用的优雅解决方案: Get usernames logged on day by day based from database

Of course, it will require adjustments, but the principle is great.当然,它需要调整,但原则是伟大的。

It's often useful to keep a table of incrementing values, as large as you need it to be:保留一个递增值的表通常很有用,只要你需要它:

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)

With such a table, producing a list of any size is trivial.使用这样的表,生成任何大小的列表都是微不足道的。 This will give you 36 date/time values a month apart, starting with the current date/time.这将为您提供相隔一个月的 36 个日期/时间值,从当前日期/时间开始。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从日期列表中查找当月的最早日期 - Find Oldest Date in Current Month from List of Dates BigQuery:获取当前月份直到当前日期的日期列表 - BigQuery: Get a List of Dates for current month until current date 连接两个日期表的问题,从客户创建日期开始到当前日期结束? - trouble joining two date tables with consecutive dates starting at customer create date and ending at current date? SQL 列出当月日期以前的销量 - SQL List previous sales of dates in the current month 我怎样才能得到从当天,当月或当年的第一天到当天的一周,一个月或一年的日期? - How could I get the the date of the week, month or year starting from the first day up to the current day of the current week, month or year? 如何在SSRS报表中获取当月的开始和结束日期 - How to get Current Month's Starting and End dates in SSRS report "在oracle sql中获取从第1个月到当前日期的数据" - get the data starting from 1st month till current date in oracle sql 如何汇总从开始月份到当前月份的记录 - How to sum up records from starting month to current per month 获取两个不同年份中当前日期(月份)的月份列表和记录 - Obtain a list of month and records from the current date(month) in two different years 从特定月份开始的 3 年日期范围 - 3 year date range starting from particular month
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM