Как рассчитать столбец даты на основе двух других атрибутов?

Я должен рассчитать поле даты во время выполнения на основе 2 других полей.

----------------------------------------------------------
Run Date   ||     Schedule       ||  Next Bill run date
-----------------------------[enter image description here][1]-----------------------------
----------------------------------------------------------
11/29/2018 ||     1st        ||  12/01/2018
----------------------------------------------------------
11/29/2018  ||     15th      ||   12/15/2018
----------------------------------------------------------
12/02/2018 ||   1st    ||   12/01/2019
----------------------------------------------------------
12/02/2018  ||  15th     ||      12/15/2018
----------------------------------------------------------
12/16/2018 ||   15th     ||     01/15/2019
----------------------------------------------------------

В приведенном выше сценарии дата запуска следующего счета должна быть заполнена на основе предыдущих 2 столбцов. Есть 4 условия,

  1. если день (Run_date) между 2–15 числами того же месяца и значением расписания - "15-е", то "Next Bill Run Run" будет 15-го числа того же месяца.

  2. если день (Run_date) между 16-м (тот же месяц) - 1-м (следующий месяц) и значением расписания является "15-е", то "Next Bill Run Run" будет 15-го числа следующего месяца.

  3. если день (Run_date) между 2–15 числами того же месяца и значением расписания равен "1st", то "Next Bill Run Run" будет 1-го числа следующего месяца.

  4. если день (Run_date) между 16 (тем же месяцем) - 1 (следующим месяцем) и значением расписания является "1st", то "Next Bill Run Run" будет 1го числа следующего месяца.

Пожалуйста, смотрите таблицу выше для лучшего понимания. Пожалуйста, помогите мне найти логику для реализации "Next Bill Run". Ценю твою помощь.

Я думаю об использовании функции case для получения datepart() даты выполнения. Но все еще путают с реализацией

3 ответа

Да, ваша логика верна. Использовать case заявление вместе с некоторыми из DATE функции в SQL SERVER. С моим ограниченным знанием функций даты SQL SERVER я сформулировал следующий запрос. Вы все еще можете оптимизировать это.

SELECT   
   RUN_DATE,SCHEDULE,
   case 
   when (DATEPART(month,run_date)=month(sysdatetime()) --checking same month
   and DATEPART(day, run_date) between 2 and 15 and Schedule='15th') --checking date between 2nd and 15th and schedule is 15th
   then DATEADD(month, DATEDIFF(month, 0,run_date), 0)+14  --selecting 15th of same month

   when (DATEPART(month,run_date)=month(sysdatetime()) 
   and DATEPART(day, run_date) between 2 and 15 and Schedule='1st') --checking date between 2nd and 15th and schedule is 1st
   then DATEADD(month, DATEDIFF(month, 0,run_date)+1, 0) --selecting 1st of next month

   when (DATEPART(month,run_date)=month(sysdatetime()) or run_date=DATEADD(month, DATEDIFF(month, 0,run_date)+1,0)) 
   and (((DATEPART(day, run_date) between 16 and 31) or (run_date=DATEADD(month, DATEDIFF(month, 0,run_date)+1,0))) 
   and Schedule='1st') 
   then case when (run_date=DATEADD(month, DATEDIFF(month, 0,run_date),0)) 
             then
             DATEADD(month, DATEDIFF(month, 0,run_date),0) -- if 1st of next month, select first day of same month
             else
             DATEADD(month, DATEDIFF(month, 0,run_date)+1,0) --selecting 1st of next month
             end
   when (DATEPART(month,run_date)=month(sysdatetime()) or run_date=DATEADD(month, DATEDIFF(month, 0,run_date),0)) 
   and (((DATEPART(day, run_date) between 16 and 31) or (run_date=DATEADD(month, DATEDIFF(month, 0,run_date),0))) 
   and Schedule='15th') 
   then case when (run_date=DATEADD(month, DATEDIFF(month, 0,run_date),0)) 
             then
             DATEADD(month, DATEDIFF(month, 0,run_date),0)+14 -- if 1st of next month, select 15 of same month
             else
              DATEADD(month, DATEDIFF(month, 0,run_date)+1,0)+14 --selecting 15th of next month
             end
    end as NEXT_BILL_RUN_DATE
FROM mytable ;    

Надеюсь, что этот запрос поможет вам.

set @lastDate := (SELECT LAST_DAY(now()) AS first_day);
set @firstDate := (SELECT DATE_ADD(DATE_ADD(LAST_DAY(now()),INTERVAL 1 DAY),INTERVAL - 1 MONTH) AS first_day);
select run_date,schedule,
case
when run_date between @firstDate and DATE_ADD(@firstDate, INTERVAL 14 DAY) and schedule ='15th' then DATE_ADD(@firstDate, INTERVAL 14 DAY)
when run_date between DATE_ADD(@firstDate, INTERVAL 15 DAY) and DATE_ADD(@firstDate, INTERVAL 1 MONTH) and schedule ='15th' then date_add(DATE_ADD(@firstDate, INTERVAL 14 DAY), INTERVAL 1 MONTH)
when run_date between @firstDate and DATE_ADD(@firstDate, INTERVAL 14 DAY) and schedule ='1st' then DATE_ADD(@firstDate, INTERVAL 1 MONTH)
when run_date between DATE_ADD(@firstDate, INTERVAL 15 DAY) and DATE_ADD(@firstDate, INTERVAL 1 MONTH) and schedule ='1st' then DATE_ADD(@firstDate, INTERVAL 1 MONTH)
end
as next_bill_run_date 
from your_table

в SQL Server

declare @firstDate as date = '01-'+month(getdate())+'-'+year(getdate());
select run_date,schedule,
case
when run_date between @firstDate and DATEADD(DAY,14,@firstDate) and schedule ='15th' then DATEADD(DAY,14,@firstDate)
when run_date between DATEADD(DAY,15,@firstDate) and DATEADD(MONTH, 1, @firstDate) and schedule ='15th' then DATEADD(MONTH, 1, DATEADD(DAY,14,@firstDate))
when run_date between DATEADD(DAY,14,@firstDate) and schedule ='1st' then DATEADD(MONTH, 1, @firstDate)
when run_date between DATEADD(DAY,15,@firstDate) and DATEADD(MONTH, 1 @firstDate) and schedule ='1st' then DATEADD(MONTH, 1 @firstDate)
end
as next_bill_run_date 
from your_table

case when schedule='1st' then DATEFROMPARTS(DATEPART(year, DATEADD(month, 1, RUN_DATE)), DATEPART(month, DATEADD(month, 1, RUN_DATE)), 01) when schedule='15th' and DATEPART(day, RUN_DATE)>=15 then DATEFROMPARTS(DATEPART(year, DATEADD(month, 1, RUN_DATE)), DATEPART(month, DATEADD(month, 1,RUN_DATE)), 15) when schedule='15th' and DATEPART(day, RUN_DATE)<15 then DATEFROMPARTS(DATEPART(year, RUN_DATE), DATEPART(month, RUN_DATE)), 15) end AS NEXT_BILL_RUN_DATE

Другие вопросы по тегам