Как рассчитать столбец даты на основе двух других атрибутов?
Я должен рассчитать поле даты во время выполнения на основе 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 условия,
если день (Run_date) между 2–15 числами того же месяца и значением расписания - "15-е", то "Next Bill Run Run" будет 15-го числа того же месяца.
если день (Run_date) между 16-м (тот же месяц) - 1-м (следующий месяц) и значением расписания является "15-е", то "Next Bill Run Run" будет 15-го числа следующего месяца.
если день (Run_date) между 2–15 числами того же месяца и значением расписания равен "1st", то "Next Bill Run Run" будет 1-го числа следующего месяца.
если день (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