在SQL中的两个日期之间获取月份的开始和结束日期?

时间:2013-02-25 17:20:08

标签: sql sql-server

我有以下功能,应该返回两个月之间的月份的开始和结束日期,问题是,因为本月是28天,该功能正在计算28天所有即将到来的月份因此返回以下错误值。

StartDate   EndDate
-----------------------   
2013-02-01  2013-02-28 
2013-03-01  2013-03-28 
2013-04-01  2013-04-28 



declare @sDate datetime,
        @eDate datetime;

select  @sDate = '2013-02-25',
        @eDate = '2013-04-25';

;with months as
(
  select DATEADD(mm,DATEDIFF(mm,0,@sDate),0) StartDate, 
  DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@sDate)+1,0)) EndDate

  union all
  select dateadd(mm, 1, StartDate),
    dateadd(mm, 1, EndDate)
  from months
  where dateadd(mm, 1, StartDate)<=  @eDate
)

select * from months

如何修改此选项以返回正确的日期?

4 个答案:

答案 0 :(得分:7)

试试这个;

declare @sDate datetime,
        @eDate datetime

select  @sDate = '2013-02-25',
        @eDate = '2013-04-25'

;with cte as (
  select convert(date,left(convert(varchar,@sdate,112),6) + '01') startDate,
         month(@sdate) n
  union all
  select dateadd(month,n,convert(date,convert(varchar,year(@sdate)) + '0101')) startDate,
        (n+1) n
  from cte
  where n < month(@sdate) + datediff(month,@sdate,@edate)
)
select startdate, dateadd(day,-1,dateadd(month,1,startdate)) enddate
from cte

FIDDLE DEMO

|  STARTDATE |    ENDDATE |
---------------------------
| 2013-02-01 | 2013-02-28 |
| 2013-03-01 | 2013-03-31 |
| 2013-04-01 | 2013-04-30 |

答案 1 :(得分:1)

如果您可以获得该月的第一天,请使用dateadd两次以获取最后一天。

首先,添加1个月,然后减去1天。

答案 2 :(得分:1)

尝试一下:这是一个表函数。返回还包含部分日期的月份开始日期和结束日期的表。

    CREATE FUNCTION [dbo].[Fun_GetFirstAndLastDateOfeachMonth] (
          @StartDate  DATE,
          @EndDate DATE
    )

    RETURNS @Items TABLE (
          StartDate DATE ,EndDate DATE,MonthNumber INT,YearNumber INT
    )

    AS
    BEGIN
            ;WITH cte AS (
              SELECT CONVERT(DATE,LEFT(CONVERT(VARCHAR,@StartDate,112),6) + '01') startDate,
                     MONTH(@StartDate) n
              UNION ALL
              SELECT DATEADD(MONTH,N,CONVERT(DATE,CONVERT(VARCHAR,YEAR(@StartDate)) + '0101')) startDate,
                    (n+1) n
              FROM cte
              WHERE n < MONTH(@StartDate) + DATEDIFF(MONTH,@StartDate,@EndDate)
            )
            INSERT INTO @Items
            SELECT  CASE WHEN  MONTH(startdate) = MONTH(@StartDate) THEN @StartDate ELSE startdate END AS StartDate, 
            CASE WHEN  MONTH(startdate) = MONTH(@EndDate) THEN @EndDate ELSE DATEADD(DAY,-1,DATEADD(MONTH,1,startdate)) END AS  enddate,
            MONTH(startDate) AS MonthNumner,YEAR(startDate) AS YearNumber
            FROM cte

          RETURN

    END -- End Function

在创建函数后执行此操作

SELECT * From [EDDSDBO].[Fun_GetFirstAndLastDateOfeachMonth] ('2019-02-25','2019-05-20')

答案 3 :(得分:1)

您可以使用下面的代码

create FUNCTION [dbo].fn_getfirstandenddate (
      @StartDate  DATE,
      @EndDate DATE
)
RETURNS @Items TABLE (
      StartDate DATE ,EndDate DATE
)AS
BEGIN
insert into @ItemsSELECT case when @startdate > DATEADD(DAY,1,EOMONTH((DATEADD(MONTH, x.number, @StartDate)),-1)) then @startdate else DATEADD(DAY,1,EOMONTH((DATEADD(MONTH, x.number, @StartDate)),-1)) end startDay,case when @enddate < eomonth(DATEADD(MONTH, x.number, @StartDate)) then @enddate else eomonth(DATEADD(MONTH, x.number, @StartDate)) end endDate FROM    master.dbo.spt_values x WHERE   x.type = 'P'AND     x.number <= DATEDIFF(MONTH, @StartDate, @EndDate);

      RETURN

END