2012-03-22 4 views
1

Я прочитал несколько статей о датах и ​​расписаниях в SQL, но решение моей проблемы продолжает ускользать от меня.SQL - функция для получения следующей даты выполнения (или просроченной даты)

Я использую SQL Server 2008 r2.

Мне нужно предоставить пользователю следующую дату (даже если это было в прошлом). Пользователь может создать расписание для импорта некоторых данных, указав частоту (ежедневно, еженедельно, ежемесячно), «множитель» (т.е. каждые 3 дня, каждые 2 недели, каждые 6 месяцев и т. Д.) И начало Дата.

Итак, мои данные выглядит примерно так:

Frequency | Multiplier | Start date 
Weekly | 2   | 02/15/2012 
Monthly | 1   | 03/01/2012 

Первая запись будет планировать импорт каждые 2 недели, начиная с 2/15/2012 Вторая запись будет каждый месяц на 1 (может быть проблемой, если они выберут 31-ю, еще не рассмотрели это).

У меня также есть последняя дата импорта, которая может быть или не быть вовремя. Итак, я хочу написать функцию, в которой я могу передавать частоту (еженедельно, ежедневно и т. Д.), Множитель и последнюю дату импорта, и рассчитывать, когда следующая «дата погашения» после последнего импорта Дата.

Итак, данная запись 1 выше (Импорт каждые 2 недели, начиная с 2/15/2012). Если у меня есть последняя дата импорта 3/1/2012, мне нужно будет вернуться 3/14/2012. Очевидно, учитывая, что сегодня 22-го числа, эта дата будет просрочена, и я мог бы отметить ее как таковой в любом пользовательском интерфейсе, который использует эти данные. Если моя последняя дата импорта - 3/22/2012, я вернусь 3/28/2012 в качестве следующей установленной даты и так далее. Возможно, мне понадобится разбить разные частоты (день, неделю, месяц) на три функции, чтобы упростить логику.

Я посмотрел в таблицу Календарь as described here.

Однако, если решение есть, я не уверен, что это точно. Я чувствую себя очень близко к решению, но просто еще не получил его.

Любая помощь очень ценится.

Спасибо, Тони

+0

спасибо за редактирование Сэма. Выглядит намного лучше. –

+0

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

+0

Thit, пожалуйста, см. Третий абзац после таблицы для иллюстрации и ожидаемых результатов. Благодарю. –

ответ

2

EDIT (с учетом позднего импорта): Если предположить, что график таблицы имеет поле ID, попробуйте:

;with cte as (
select 0 n, [Start date] as ScheduleDate, [Frequency], [Multiplier] 
from ScheduleTable where [ID] = @ScheduleID 
union all 
select n+1 n, 
     case [Frequency] 
      when 'Weekly' then dateadd(Week, [Multiplier], ScheduleDate) 
      when 'Daily' then dateadd(Day, [Multiplier], ScheduleDate) 
      when 'Yearly' then dateadd(Year, [Multiplier], ScheduleDate) 
      ... 
     end as ScheduleDate, 
     [Frequency], 
     [Multiplier] 
from cte 
where n < 32767 and ScheduleDate <= @LastImportDate) 
select max(ScheduleDate) as NextDueDate from CTE 
option (maxrecursion 32767) 
+0

К сожалению, все не так просто. Последнее значение lastmartdate может не совпадать с последней установленной датой. Возможно, это было импортировано через 3 дня, 2 дня раньше и т. Д. –

+0

@ AnthonyQueen: См. Обновленный ответ. –

+0

@ Марк Баннистер: Интересно ... Я никогда не думал об этом.Я приспособию его к моей схеме и посмотрю, что я получу, и дам вам знать. Благодарю. –

Смежные вопросы