我必须基于其他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个条件,
如果同一月2日至15日与计划值之间的日期(运行日期)为“ 15”,则“下一次帐单运行”将为同一月的15日。
如果第16个(同一月)至1月(下一个月)与计划值之间的日期(运行日期)为“ 15”,则“下一个帐单运行”将是下个月的15号。
如果同一月2日至15日之间的日(运行日期)与计划的值是“ 1st”,则“下一次帐单运行”将是下个月的1号。
如果第16个(同一月)至1月(下个月)与计划值之间的日期(运行日期)为“ 1st”,则“下一个帐单运行”将为下个月的1号。
请参阅上表以获得更好的理解。请帮助我找出实施“下一个条例草案”的逻辑。感谢您的帮助。
我正在考虑使用'case'函数获取运行日期的datepart()。但是仍然与实现混淆
答案 0 :(得分:1)
希望以下查询对您有所帮助。
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
答案 1 :(得分:1)
是的,您的逻辑是正确的。将case
语句与SQL SERVER中的某些DATE
函数一起使用。据我对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 ;
答案 2 :(得分:0)
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