Получите даты начала и даты окончания месяца промежуточные две даты в SQL?

У меня есть следующая функция, которая, как предполагается, возвращает даты начала и даты окончания месяцев промежуточные два месяца, проблема, как когда-либо то, что, так как этот месяц составляет 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

как я могу изменить это, чтобы возвратить правильные даты?

2
nl ja de
Вы shouldn' t использовать содержащую верхнюю границу - необходимо говорить ' меньше, чем начало следующего month'. It' s неправильный способ думать о ценностях даты/времени/метки времени, и у по-видимому SQL Server есть уникальный набор проблем имея дело с этим, также. Так, получите начало месяца, добавьте месяц и используйте содержащую нижнюю границу (> = ), и исключительная верхняя граница ( <).
добавлено автор Clockwork-Muse, источник

2 ответы

Попробуйте это;

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

ИГРАЮТ ДЕМОНСТРАЦИОННЫЙ ПРИМЕР

|  STARTDATE |    ENDDATE |
---------------------------
| 2013-02-01 | 2013-02-28 |
| 2013-03-01 | 2013-03-31 |
| 2013-04-01 | 2013-04-30 |
6
добавлено
могли вы комментировать код и объяснять что его выполнение, благодарить
добавлено автор Xerxes, источник
В стороне cte, это получает startdates каждого месяца между данными датами и затем стороной cte, я использую startdate, чтобы найти дату окончания того же самого месяца, используя dateadd функцию. Это работает, даже если вы даете даты через два года. Игра со скрипкой вы поймете.
добавлено автор Kaf, источник

Если можно получить первый день месяца, используйте dateadd дважды, чтобы добраться в последний день.

Во-первых, добавьте 1 месяц, затем вычтите 1 день.

1
добавлено
SqlCom.ru - Стиль жизни SQL
SqlCom.ru - Стиль жизни SQL
908 участник(ов)

Правила чата - https://t.me/sqlcom/88269 @sqlcom - основной канал (только MS SQL) @sql_ninja - второй канал (SQL вопросы начального уровня и свободное общение) @Gopnegbot - Викторина по SQL Server (наберите в привате /quiz). Предложения в @sql_ninja

SQL_Ninja
SQL_Ninja
340 участник(ов)

Правила чата - https://t.me/sqlcom/88269 @sqlcom - основной канал (только SQL) @sql_ninja - второй канал (SQL вопросы начального уровня и свободное общение) @Gopnegbot - Викторина по SQL Server (наберите в привате /quiz)