SQL повторяется каждые х дней недели каждые х недель - PullRequest
1 голос
/ 14 декабря 2011

Я пытаюсь написать sql-запрос, который в зависимости от того, что выберет пользователь, будет повторяться каждые x дней, каждые x недель. Таким образом, пользователь будет выбирать, что он хочет, чтобы работа повторялась по вторникам каждые 2 недели. предоставленные значения:

declare @StartDate datetime -- when the job first recurs
declare @recurrenceValue1 int -- amount of weeks
declare @recurrenceValue2 int -- day of week (mon-sun)
declare @NextOcurrance datetime -- when the job will recur

Я знаю, как установить его на количество недель:

SET @NextOccurance = (Convert(char(12),@StartDate + (@RecurrenceValue1),106))

Но я не уверен, как заставить его переходить на день недели, поэтому, если @startDate сегодня, и он должен повторяться каждые 2 недели во вторник, он увидит, что 2 недели сегодня среда, поэтому будет цикл пока он не узнает, что это вторник, и это будет дата @NextRecurrance.

Заранее спасибо

Ответы [ 3 ]

2 голосов
/ 16 декабря 2011

Простой способ добавить количество недель к дате - использовать ( MSDN DATEADD )

DATEADD(wk, @StartDate, @recurrenceValue1)

Чтобы узнать, к какому дню недели относится дата, на которую вы смотрите, вы можете использовать ( MSDN DATEPART )

DATEPART(dw, @StartDate)

Эта функция использует DATEFIRST, чтобы определить, какой день недели является первым (http://msdn.microsoft.com/en-us/library/ms181598.aspx)

SET DATEFIRST 1 --Where 1 = Monday and 7 = Sunday

Так что для вашей проблемы (DATEFIRST устанавливается в 1 = понедельник) ..

SET DATEFIRST 1

declare @StartDate datetime -- when the job first recurs
declare @recurrenceValue1 int -- amount of weeks
declare @recurrenceValue2 int -- day of week (mon-sun)
declare @NextOcurrance datetime -- when the job will recur


SET @StartDate = '2011-12-16' -- This is a Friday
SET @recurrenceValue1 = 2 -- In 2 weeks
SET @recurrenceValue2 = 2 -- On Tuesday
SET @NextOcurrance = DATEADD(wk, @recurrenceValue1, @StartDate) -- Add our 2 weeks
/* Check if our incrementation falls on the correct day - Adjust if needed */
IF (DATEPART(dw, @NextOcurrance) != @recurrenceValue2) BEGIN
    DECLARE @weekDay int = DATEPART(dw, @NextOcurrance)
    SET @NextOcurrance = DATEADD(dd, ((7 - @weekDay) + @recurrenceValue2), @NextOcurrance) -- Add to @NextOcurrance the number of days missing to be on the requested day of week
END

Логика для добавления количества дней следующая: У нас есть 7 дней в неделю, сколько дней нужно, чтобы достичь конца этой недели. Добавьте это количество дней к @ recurrenceValue2 (день недели, который мы ищем).

PS: я не могу опубликовать более 2 гиперссылок из-за своей репутации. Вот почему URL DATEFIRST находится в текстовом формате.


Вот код, позволяющий по-разному обрабатывать определенную дату. Хотя этот код хорош только для уникальных дат. Например, если нужно пропустить целую неделю, использование этого кода потребует добавления значений для каждого дня этой недели, чтобы пропустить. Для диапазонов, отличных от уникальных дней, этот код следует изменить для обработки диапазонов дат или определенных недель и / или дней недели.

CREATE TABLE OccurenceExclusions (
    ExclusionDate DATE not null,
    NumberOfDaysToAdd int not null

    PRIMARY KEY (ExclusionDate)
)

INSERT OccurenceExclusions VALUES ('2012-01-01', 7)

SET @NextOcurrance = DATEADD(dd, COALESCE((SELECT NumberOfDaysToAdd
                           FROM OccurrenceExclusions
                           WHERE ExclusionDate = @NextOcurrance), 0), @NextOcurrance)
0 голосов
/ 19 декабря 2011

Используя принципы, изложенные @DanielM, я изменил его, чтобы соответствовать моему запросу, см. Ниже:

    BEGIN
    SET DATEFIRST 1 --Where 1 = Monday and 7 = Sunday 
    declare @StartDate datetime -- when the job first recurs   
    declare @recurrenceValue1 int -- amount of weeks   
    declare @recurrenceValue2 int -- day of week (mon-sun)   
    declare @NextOcurrance datetime -- when the job will recur   
                        -- sets @nextoccurence to next date after x amount of weeks
 SET @NextOccurance = DATEADD(wk, @recurrenceValue1, @StartDate) -- Add on weeks /* Check if our incrementation falls on the correct day - Adjust if needed */ 
                        IF (DATEPART(dw, @NextOccurance) != @recurrenceValue2) 
                        BEGIN  
                        DECLARE @Weekday int = DATEPART(dw, @NextOccurance)      
                        SET @NextOccurance = DATEADD(dd, (@RecurrenceValue2 - @Weekday), @NextOccurance) -- Add to @NextOcurrance the number of days missing to be on the requested day of week
                        END
                    END
0 голосов
/ 16 декабря 2011

Вероятно, лучшим решением будет использование таблицы календаря.http://web.archive.org/web/20070611150639/http://sqlserver2000.databases.aspfaq.com/why-should-i-consider-using-an-auxiliary-calendar-table.html

Вы можете запросить его следующим образом:

SELECT TOP 1 @NextOccurance = Date
FROM CalendarTable
WHERE Date >= DATEADD(week, @recurranceValue1, @StartDate)
AND DateName = @recurranceValue2
...