Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 表驱动的付款计划_Sql_Sql Server_Tsql - Fatal编程技术网

Sql 表驱动的付款计划

Sql 表驱动的付款计划,sql,sql-server,tsql,Sql,Sql Server,Tsql,My Payment Schedule(我的付款计划)保存一行付款计划,该付款计划基于“生效日期”在特定日期运行 CREATE TABLE [dbo].[PaymentSchedule] ( [PaymentScheduleId] INT IDENTITY (1, 1) NOT NULL, [EffectiveDate] DATE NOT NULL, [EffectiveDays] INT NOT NULL, CONSTRAINT [pk_Pa

My Payment Schedule(我的付款计划)保存一行付款计划,该付款计划基于“生效日期”在特定日期运行

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)
);
因此,如果生效日期为“2013年1月1日”,而“生效日期”为7,则付款日期为1月1日,之后每7天付款一次。因此,1月8日必须付款。必须在15日付款。。等等

如果生效日期为“2013年1月1日”,生效日期为20天,则第一次付款日期为1月1日,下一次付款日期为1月21日,之后的第二次付款日期为2013年2月9日。。等等

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


这能有效地做到吗?在7年的时间内,我是否能够判断某个日期是否为付款日,例如?

您可以使用方法DATEDIFFdatepart、startdate、enddate设置为datepart dayofyear,该方法的结果将给出两个日期之间的天数,并将该结果除以有效天数(以模数%表示),如果结果为0,则为付款日;如果没有,您将从最后一个付款日开始计算天数,如果您从有效日期开始计算,则您必须将重新开始的天数计算到下一个付款日

以下是DATEDIFF方法的一些文档:
您对问题的描述是错误的。如果第一次付款是在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

我将其结构化为一个子查询,将当前日期定义为今天。这使得您可以更轻松地替换您可能需要的任何其他日期。

我可能回答了错误的问题,但我认为下面的代码将返回符合所选付款日期的付款计划,如果您正在寻找的是该日期

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)
;

从1月1日到7日的间隔为6天。从7号到14号的间隔是7天。您确定您的示例指定正确吗?这看起来很有希望,但我得到一个错误,运行第二个查询时,操作数类型clash:date与int不兼容。