给出以下数据库表:
StartDate DATETIME -- day that the reminder period starts
LastReminderDate DATETIME -- the last time the reminder triggered
DayOfMonth INT -- the day of the month to remind the user
Interval INT -- how often in months to remind the user
如何根据这些值找出下一个提醒日期?例如:
StartDate = '6/1/2011'
LastReminderDate = '6/5/2011'
DayOfMonth = 5 -- remind on the 5th of the month
Interval = 2 -- remind every other month
对于此特定示例,下一个提醒日期应为2011年8月5日,因为它会在每月的第5个月提醒。我如何编写一个函数来解决这个问题?
如果LastReminderDate为NULL,那么LastReminderDate应该等于StartDate
更新:
StartDate = '6/1/2011'
LastReminderDate = NULL
DayOfMonth = 5
Interval = 2
在这种情况下,没有最后提醒日期。第一次提醒将是2011年6月5日。在这种情况下,下面的解决方案似乎返回8/5。
以下是一些具体规则:
答案 0 :(得分:2)
DECLARE
@StartDate AS datetime, -- day that the reminder period starts
@LastReminderDate AS datetime, -- the last time the reminder triggered
@DayOfMonth AS integer, -- the day of the month to remind the user
@Interval AS integer -- how often in months to remind the user
SET @StartDate = '6/1/2011'
SET @LastReminderDate = '6/5/2011'
SET @DayOfMonth = 5 -- remind on the 5th of the month
SET @Interval = 2 -- remind every other month
SELECT
CASE
WHEN @LastReminderDate IS NULL
THEN
CASE WHEN Day(@StartDate) <= @DayOfMonth
THEN DateAdd( month, ((Year( @StartDate ) - 1900) * 12) + Month( @StartDate ) - 1, @DayOfMonth - 1 )
ELSE DateAdd( month, ((Year( @StartDate ) - 1900) * 12) + Month( @StartDate ) - 0, @DayOfMonth - 1 )
END
ELSE DateAdd( month, @Interval, @LastReminderDate )
END
这是最后四行,即SELECT CASE ... END
陈述。我提供了一个完整的脚本,允许您插入不同的值,并查看SELECT CASE ... END
对这些测试值的行为。
但是要在你的桌面上使用它,只使用最后四行(并从名称前面删除@
,使它们与表的列名匹配)。
您也可以对此进行概括,以便Interval不必是几个月。如果您的表具有IntervalType列,则可以将其作为DateAdd()
的第一个参数提供。请参阅文档,但有些常见的时间间隔为days
,months
,years
,等等。
EDIT2:尊重DayOfMonth。
答案 1 :(得分:0)
如果你想在没有LastReminderDate的情况下使用StartDate,那么你会想要使用COALESCE来获得那个逻辑:COALESCE(LastReminderDate, StartDate)
现在,转到上个月的最后一天:DATEADD(DAY, -DAY(COALESCE(LastReminderDate, StartDate)), COALESCE(LastReminderDate, StartDate))
最后,添加月份,然后到达我们需要的日期:
DATEADD(MONTH, Interval, DATEADD(DAY, -DAY(COALESCE(LastReminderDate, StartDate)) + DayOfMonth, COALESCE(LastReminderDate, StartDate)))
如果最后一次提醒的日期是在为提醒配置的“DayOfMonth”之后的某一天的某一天,这可能会持续不到两个月。您应该能够根据您的业务逻辑在那种情况下进行调整。