3

我的付款计划根据“生效日期”为在特定日期运行的付款计划保留一行。

CREATE TABLE [dbo].[PaymentSchedule] (
    [PaymentScheduleId] INT  IDENTITY (1, 1) NOT NULL,
    [EffectiveDate]     DATE NOT NULL,
    [EffectiveDays]     INT  NOT NULL,
    CONSTRAINT [pk_PaymentSchedule] PRIMARY KEY CLUSTERED ([PaymentScheduleId] ASC)
);

因此,如果effectivedate是 '01-JAN-2013',而 ' EffectiveDays' 是 7,则在 1 月 1 日付款,然后每 7 天付款一次。因此,必须在 1 月 8 日付款。15日,必须付款..等等。

如果effectivedate是 '01-JAN-2013',并且EffectiveDays是 20,那么第一次付款是 1 月 1 日,下一个付款日是 1 月 21 日,之后的下一个付款日是 2013 年 2 月 9 日..等等等等

我想要做的是创建一个使用上表的函数,或者一个存储过程,它返回“下一个付款日期”,并采用 DATE 类型。那么,根据传入的日期,下一个付款日期是什么时候?还有,“今天是付款日期吗”。

这可以有效地完成吗?例如,在 7 年后,我能否判断某个日期是否为付款日?

4

3 回答 3

1

您可以使用方法 DATEDIFF(datepart, startdate, enddate) 设置为 datepart "dayofyear" 此方法的结果将为您提供两个日期之间的天数,并将此结果除以 EffectiveDays 和如果结果为 0,则有付款日;如果没有,您将拥有从最后一个付款日开始的天数(如果您将其从 EffectivedDays 中删除,则您必须将剩余天数保留到下一个付款日)。

这是 DATEDIFF 方法的一些文档:http: //msdn.microsoft.com/en-us/library/ms189794.aspx

于 2013-06-08T12:09:30.010 回答
1

你对问题的描述是错误的。如果第一次付款是在 1 月 1 日,则后续付款将在 1 月 8 日、1 月 15 日等等。

关于当前日期的问题的答案datediff()与模运算符一起。要查看今天是否是付款日期,请取差值并查看它是否是您正在查看的期间的精确倍数:

select getdate()
from PaymentSchedule ps
where datediff(day, ps.EffectiveDate, getdate()) % ps.EffectiveDays = 0;

%是取两个值之间的余数的模运算符。所以,3%2是 1,10%5是 0。

对于下一个日期,答案是相似的:

select dateadd(day,
               ps.EffectiveDays - datediff(day, ps.EffectiveDate, today) % ps.EffectiveDays,
               today) as NextDate
from PaymentSchedule ps cross join
     (select cast(getdate() as date) as today) const

我将其构建为一个子查询,将当前日期定义为today. 这样可以更轻松地替换您可能想要的任何其他日期。

于 2013-06-08T12:16:08.030 回答
0

我可能回答错了问题,但我认为以下代码会返回到达所选付款日期的付款时间表,如果这是您要查找的内容?

IF OBJECT_ID('tempdb..#PaymentSchedules') IS NOT NULL
    DROP TABLE #PaymentSchedules;

CREATE TABLE #PaymentSchedules
( PaymentScheduleID INT NOT NULL IDENTITY(1,1)
  CONSTRAINT PK_PaymentSchedules_PaymentScheduleID PRIMARY KEY
, EffectiveDate DATE NOT NULL
, EffectiveDays INT NOT NULL )
;

INSERT #PaymentSchedules (EffectiveDate, EffectiveDays)
VALUES
  ('20120401', 3)
, ('20120401', 2)
, ('20120401', 1)
, ('20120401', 7)
, ('20120401', 14)
;

DECLARE @PaymentDate DATE = '20140310';

WITH myCTE AS
(
  SELECT PaymentScheduleID, PaymentDate = EffectiveDate, EffectiveDays
  FROM #PaymentSchedules
  UNION ALL
  SELECT PaymentScheduleID, PaymentDate = DATEADD(DAY, EffectiveDays, PaymentDate), EffectiveDays
  FROM myCTE
  WHERE DATEADD(DAY, EffectiveDays, PaymentDate) <= @PaymentDate
)

SELECT * FROM myCTE
WHERE PaymentDate = @PaymentDate
OPTION (MAXRECURSION 10000)
;
于 2013-06-08T23:00:14.503 回答