我正在开发一个处理定期付款的应用程序 付款每两周进行一次,即
现在我需要一个SQL语句,可以计算WHERE子句中给定日期最近的下一个付款日期
即。 SELECT ... FROM ... WHERE someDate< [从给定日期计算下一个付款日期]
如果我在C#中这样做,我会去
static DateTime CalculateNextPayDateFrom(DateTime fromDate)
{
var firstEverPayment = new DateTime(2009, 6, 1);
var nextPayment = firstEverPayment;
while (nextPayment < fromDate)
{
nextPayment += new TimeSpan(14, 0, 0, 0);
}
return nextPayment;
}
所以如果我这样做
Console.WriteLine(CalculateNextPayDateFrom(new DateTime(2009, 6, 12)).ToString());
Console.WriteLine(CalculateNextPayDateFrom(new DateTime(2009, 6, 20)).ToString());
输出
15/06/2009 12:00:00 a.m.
29/06/2009 12:00:00 a.m.
但是当我必须在SQL中执行此操作时,我完全陷入困境。
任何人都可以帮我解决这个问题吗?我正在使用SQL Server 2005
更新: 顺便说一句,我忘了提到数据库中没有最后的付款日期,必须在运行时计算。
答案 0 :(得分:3)
要正确进行计算,您需要我所指的参考日期,例如:从您开始2周周期的日期。 (在您的代码中表示firstEverPayment声明)
鉴于您可以确定从现在到参考之间的天数,以获得天数。 除以14,但使用Floor向下舍入(例如计算出已经发生了多少2周的间隔) 添加1 - 向前移动两周的间隔。 (您可以使用天花板而不是地板跳过添加1) 乘以14 - 得到天数 使用添加日期添加那些日子。
像
这样的东西select dateadd(dd,(Ceiling(datediff(dd,'1/1/09',getdate())/ 14)* 14),'1/1/09')
我使用1/1/09作为参考日期。
答案 1 :(得分:2)
这样的事情怎么样。抓住当年的当天,除以14得到余数,然后将差值从14添加到您的日期。您可能需要调整DaysOfYear以匹配您当年的第一笔付款......
declare @mydate datetime
set @mydate = '20090607'
select DATEADD(dd, 14 - DATEPART(dayofyear, @mydate) % 14, @mydate)
set @mydate = '20090611'
select DATEADD(dd, 14 - DATEPART(dayofyear, @mydate) % 14, @mydate)
set @mydate = '20090612'
select DATEADD(dd, 14 - DATEPART(dayofyear, @mydate) % 14, @mydate)
set @mydate = '20090617'
select DATEADD(dd, 14 - DATEPART(dayofyear, @mydate) % 14, @mydate)
答案 2 :(得分:0)
使用dateadd
!
create procedure GetNextDate
(
@StartDate datetime,
@FromDate datetime
) as
begin
select
dateadd(day,
14*cast(datediff(day, @StartDate, @FromDate) / 14 + 1 as int),
@StartDate)
end
这会在@FromDate
之后找到下一个付款日期,其开始日期为@StartDate
。
答案 3 :(得分:0)
我遇到了这个问题,试图解决一种方法,该方法可以根据不一定是过去的已知日期来计算“最近”支付期间的日期。
您的解决方案几乎让我到了那里,但这是在其他人正在寻找的情况下的完整解决方案:
(技巧是添加一个CASE / WHEN语句以检查refDate是否在testDate之前发生)
这可行:
DECLARE @refDate DATE = '3/6/18', @testDate DATE = '4/10/18'
SELECT DATEADD(DD,(CEILING(DATEDIFF(DD, @refDate, @testDate )/14)-CASE WHEN @refDate>@testDate THEN 1 ELSE 0 END)*14,@refDate)
Result:
Correctly returns "4/03/2018"
这有效:
DECLARE @refDate DATE = '3/6/18', @testDate DATE = '3/5/18'
SELECT DATEADD(DD,(CEILING(DATEDIFF(DD, @refDate, @testDate)/14)-CASE WHEN @refDate>@testDate THEN 1 ELSE 0 END)*14,@refDate)
Result:
Correctly returns "2/20/2018"