我的付款时间表根据“生效日期”为特定日期的付款时间表保留一行。
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年时间内,我能判断一个日期是否是付款日吗?
答案 0 :(得分:1)
您可以使用方法DATEDIFF(datepart,startdate,enddate)设置为datepart“dayofyear”,此方法的结果将为您提供两个日期之间的天数,并将此结果除以Modulo(%) EffectiveDays,如果结果为0则有付款日;如果没有,您将从最后一个付款日过去(如果您从有效日期提取它,您必须将休息日提交到下一个付款日)。
以下是DATEDIFF方法的一些文档: http://msdn.microsoft.com/en-us/library/ms189794.aspx
答案 1 :(得分:1)
您对问题的描述是错误的。如果第一笔付款是1月1日,则后续付款将在1月15日1月8日,依此类推。
关于当前日期的问题的答案是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
。这样可以更容易地替换您可能想要的任何其他日期。
答案 2 :(得分: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)
;