Расчет ближайшей будущей даты периодического платежа в SQL - PullRequest
4 голосов
/ 10 июля 2009

Я работаю над приложением, которое имеет дело с периодическими платежами Платежи осуществляются каждые две недели, т.е.

  • оплата 1: 2009-06-01
  • платеж 2: 2009-06-15
  • платеж 3: 2009-06-29

и теперь мне нужен оператор SQL, который может вычислить ближайшую дату следующего платежа из заданной даты в предложении WHERE

т.е. ВЫБРАТЬ ... ОТ ... ГДЕ someDate <<em> [РАССЧИТАТЬ СЛЕДУЮЩУЮ ДАТУ ВЫПЛАТЫ ИЗ ДАННОЙ ДАТЫ]

Если бы я делал это в 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

UPDATE: Кстати, я забыл упомянуть, что последняя дата платежа не доступна в базе данных, она должна быть рассчитана во время выполнения.

Ответы [ 4 ]

3 голосов
/ 10 июля 2009

Для правильного расчета вам понадобится то, что я бы назвал контрольной датой, например, дата, с которой вы начинаете 2-недельный цикл с. (в вашем коде это первая декларация EverPayment)

Учитывая, что вы можете указать число дней между сегодняшним днем ​​и ссылкой, чтобы получить количество дней. Разделите на 14, но округлите с помощью Floor (например, определите, сколько 2-недельных интервалов уже произошло) Добавьте 1 - для продвижения вперед двухнедельный интервал. (Вы можете пропустить add 1, используя Ceiling, а не floor) Умножьте на 14 - чтобы получить количество дней Используйте дату Добавить, чтобы добавить эти дни.

Что-то вроде

выберите дату и время (дд, (Потолок (дата (дд, 1/1/09, getdate ()) / 14) * 14), 1/1/09 ')

Где я использовал 1/1/09 в качестве контрольной даты.

2 голосов
/ 10 июля 2009

как насчет этого. Возьмите текущий день года, разделите на 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)
0 голосов
/ 10 марта 2019

Я столкнулся с этим ответом, пытаясь найти способ рассчитать «ближайшую» дату платежного периода на основе известной даты, которая не обязательно была в прошлом.

Ваше решение почти привело меня туда, но это полное решение на тот случай, если кто-то еще ищет:

(хитрость заключается в том, чтобы добавить инструкцию 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"
0 голосов
/ 10 июля 2009

Использование 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...