2012-06-08 4 views
1

У меня возникла проблема с планированием рабочих мест в первую дату последнего месяца каждого квартала. Это было бы очень просто, как я могу получить последний месяц каждого квартала, а затем добавить первую дату к ней, какКвартальный расчет даты

select START_DATE, 
CONVERT(datetime,CAST(YEAR(START_DATE) as VARCHAR(4))+'/'+ 
       CAST(DATEPART(Q,START_DATE)*3 as VARCHAR(2))+'/01 00:00:00',120 
     ) as SCHEDULE_DATE_LAST_MONTH_OF_QUARTER 
from JOB_SCHEDULE_CONFIGURATION 

Камнем преткновения является START_DATE. Я проиллюстрирую на примере

START_DATE SCHEDULE_DATE_LAST_MONTH_OF_QUARTER 
2012/05/01 2012/06/01 --correct schedule 
2012/02/15 2012/03/01 --correct schedule 
2012/06/15 2012/06/01 ---problem at this line I will explain why 

Дата начала случается 2012/06/15, и я не могу планировать работу до даты начала т.е. 2012/06/01. Я должен запланировать его только после 2012/06/15, что означает, что работа должна быть запланирована на следующий квартал, т.е. 2012/09/01

Как изменить запрос? Я думаю, что может быть какая-то математика, и я действительно не преуспеваю в математике. Пожалуйста, помогите.

Благодаря

Дэвид

ответ

2
declare @T table 
(
    START_DATE date 
) 

insert into @T values 
('2012-05-01'), 
('2012-02-15'), 
('2012-06-15') 

select dateadd(month, 
       2, 
       dateadd(quarter, 
         datediff(quarter, 
           0, 
           dateadd(month, 
             case when day(START_DATE) >= 15 
              then 1 
              else 0 
             end, 
             START_DATE)), 
         0)) 
from @T 

Update:

Основная часть этого запроса, чтобы получить первую дату квартала, и что делается с помощью DateAdd/DateDiff трюк ,

select dateadd(quarter, datedifF(quarter, 0, START_DATE), 0) 
from @T 

Результат:

----------------------- 
2012-04-01 00:00:00.000 
2012-01-01 00:00:00.000 
2012-04-01 00:00:00.000 

Вы хотели последний месяц квартала, поэтому мы добавим dateadd(month, 2

select dateadd(month, 2, dateadd(quarter, datedifF(quarter, 0, START_DATE), 0)) 
from @T 

Результат:

----------------------- 
2012-06-01 00:00:00.000 
2012-03-01 00:00:00.000 
2012-06-01 00:00:00.000 

Это оставляет только часть где даты опаздывают r, чем 15-е число последнего месяца, должно быть в конце следующего квартала. day(START_DATE) предоставит вам день месяца, чтобы мы могли добавить 1 месяц к START_DATE, если day(START_DATE) >= 15 с использованием case case.

select dateadd(month, case when day(START_DATE) >= 15 then 1 else 0 end, START_DATE) 
from @T 

Результат:

---------- 
2012-05-01 
2012-03-15 
2012-07-15 

Собираем все вместе это будет выглядеть следующим образом.

select dateadd(month, 2, dateadd(quarter, datedifF(quarter, 0, dateadd(month, case when day(START_DATE) >= 15 then 1 else 0 end, START_DATE)), 0)) 
from @T 

Результат:

----------------------- 
2012-06-01 00:00:00.000 
2012-03-01 00:00:00.000 
2012-09-01 00:00:00.000 
+0

вы можете, пожалуйста, объясните логику запроса. Благодаря PS START_DATE может быть любая дата с 1-го по 31-й. Это не должно быть 15. –

+0

@davidmichell - Конечно, я обновил ответ. –

+0

Спасибо Микаэль. Понял. Супер. Спасибо за запрос и подробное объяснение. –