2014-06-12 195 views
0

我有,在有日期字段,这个日期栏称为[协议日期],并在上午的协议是由制作时创建的日期表付款。我试图根据当月的下一天计算下一次付款的时间。选择基于指定的日期SQL下一个日期2008

例如,如果协议日期是21-JAN-2014则下一个支付将是在6月21日2014年。这是我被卡住的部分,我如何让它忽略前几个月并简单地检查下一个到期日?

+1

现在真的不清楚。 21/01/2014和12/06/2014如何相互关联?正在做什么计算从一个到另一个? 21/01/2014日期甚至来自哪里?这是表格中的一列,是硬编码的吗? –

+0

@AnthonyGrist对不起,试图弄清楚一点。 – GPH

+0

付款多长时间到期?每月?季刊?每X个月(X不是像3,6,9或12那样的常见付款时间表)? –

回答

1
SELECT 
    [agreement date], 
    CASE 
    WHEN [payment date this month] >= CAST(GETDATE() AS date) 
    THEN [payment date this month] 
    ELSE [payment date next month] 
    END AS [payment date] 
FROM (
    SELECT 
    [agreement date], 
    DATEADD(
     MONTH, 
     DATEDIFF(MONTH, [agreement date], GETDATE()), 
     [agreement date]) AS [payment date this month], 
    DATEADD(
     MONTH, 
     DATEDIFF(MONTH, [agreement date], GETDATE()) + 1, 
     [agreement date]) AS [payment date next month] 
) AS sub 

DATEDIFF(MONTH, x, y)完全忽略了当天的日双方xy的。如果x是某处在一月和y是在二月的某个地方,然后DATEDIFF(MONTH, x, y)是,即使不同的是只有单一的一天。

因此,您可以使用DATEDIFF(MONTH, [agreement date], GETDATE())获得的月数增加,将确保你得到这个月的付款日期。并添加一个获取下个月的付款日期。

之后,将[payment date this month]GETDATE()进行比较以确定其是否已经通过是一件简单的事情。

+0

我收到msg错误? Msg 8155,Level 16,State 2,Line 10 没有为'sub'的列1指定列名称。 ? – GPH

+0

@Gavlaaa你能显示你尝试过的确切的SQL吗?你需要稍微调整一下我的答案才能使它适合你,并且轻微的调整可能很容易出错。 – hvd

+0

呃,谢谢你的帮助。 – GPH

0

有可能是一个更优雅的方式来做到这一点,但是这应该是由于按月支付工作:

SELECT [agreement date], 
CASE WHEN DATEPART(DAY, [agreement date]) > 28 THEN 
    CONVERT(DATE, CAST(DATEPART(YEAR, GETDATE()) AS NVARCHAR(4)) + '/' + CAST(DATEPART(MONTH, GETDATE()) AS NVARCHAR(2)) + '/28', 111) 
ELSE 
    CONVERT(DATE, CAST(DATEPART(YEAR, GETDATE()) AS NVARCHAR(4)) + '/' + CAST(DATEPART(MONTH, GETDATE()) AS NVARCHAR(2)) + '/' + CAST(DATEPART(DAY, [agreement date]) AS NVARCHAR(2)), 111) 
END AS [Next payment due date] 
FROM yourTable 

注意,它会产生上,如果在本月28日付款到期日协议日期已过,以解决无效日期的任何潜在问题(如2月31日)。

+0

这可能会在今天之前返回,例如,如果协议日期是一个月的十五号,而今天是二十号。 – hvd

+0

@ hvd你说得对,我只做了最小的测试。可以用另一个CASE语句来解决这个问题,但这会变得非常混乱。我想知道是否有更好的方法来生成部分日期。 –

相关问题