每个月的两个日期之间的开始和结束

时间:2018-07-09 13:00:18

标签: sql sql-server tsql date

给出两个@START_DATE@END_DATE参数,我想编写一个查询,该查询为两个之间存在的每个月生成一对(month_start_date,month_end_date)天,包括那些日期。

例如如果@START_DATE = '2018-01-14'@END_DATE = '2018-05-04'(yyyy-MM-dd),我希望输出为

month_start_date, month_end_date
2018-01-01, 2018-01-31
2018-02-01, 2018-02-28
2018-03-01, 2018-03-31
2018-04-01, 2018-04-30
2018-05-01, 2018-05-31

3 个答案:

答案 0 :(得分:1)

为此,我倾向于使用递归CTE:

with dates as (
      select datefromparts(year(@start_date), month(@start_date), 1) as dte
      union all
      select dateadd(month, 1, dte)
      from dates
      where dateadd(month, 1, dte) <= @end_date
     )
select dte as start_date, eomonth(dte) as end_date
from dates;

此功能最多可使用100个月。除此之外,您需要使用设置最大递归选项。

答案 1 :(得分:1)

您需要recursive cte:

with t as (
     select dateadd(day, 1, eomonth(@START_DATE, -1)) as start_dt, @END_DATE as end_dt
     union all
     select dateadd(mm, 1, start_dt), end_dt
     from t
     where dateadd(mm, 1, start_dt)  < @END_DATE
)

select start_dt as month_start_date, eomonth(start_dt) as month_end_date
from t
option (maxrecursion 0);

答案 2 :(得分:1)

以下查询返回所需结果。

declare @StartDate date = '2018-01-14'
      , @EndDate   date = '2018-05-04';
;with Months as (
select top (datediff(month,@StartDate,@EndDate)+1) 
    [month_start_date] = dateadd(month
               , datediff(month, 0, @StartDate) + row_number() over (order by number) -1
               , 0)
    , month_end_date = dateadd(day,-1,dateadd(month
               , datediff(month, 0, @StartDate) + row_number() over (order by number) 
               ,0))
  from master.dbo.spt_values
  order by [month_start_date]
)
select * from Months;