【问题标题】:SQL Recur every x weekday every x weeksSQL 每 x 周每 x 周重复一次
【发布时间】:2011-12-14 11:56:05
【问题描述】:

我正在尝试编写一个 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 是今天,它应该在星期二每两周重复一次,它会看到今天是星期三,所以会循环直到它知道今天是星期二,那将是 @NextRecurrance 日期。

提前致谢

【问题讨论】:

  • 嗨,是的,我正在使用 sqlserver2008
  • 您想要“星期三 + 2 周”之前的星期二,还是“星期三 + 2 周”之后的星期二?如果有人将第一个“重复”日期定为星期二,但星期几应该是星期三,这种情况会改变吗?您是否正在尝试为调度服务编写函数或存储数据(如果是,您的架构是什么,您可以更改它吗)?
  • @X-Zero 如果用户选择今天的开始日期,则作业将在今天运行,那么计划任务将运行上述过程。然后需要将 NextOccurance 日期设置为 2 周后的星期二

标签: sql sql-server-2008 datetime recurrence


【解决方案1】:

在日期上添加周数的简单方法是使用 (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 个超链接。这就是为什么 DATEFIRST URL 是纯文本的原因。


这里有一些代码允许以不同方式处理某些特定日期。尽管此代码仅适用于唯一日期。例如,如果需要跳过一整周,则使用此代码将需要为本周的每一天添加值以跳过。对于唯一日期以外的范围,应修改此代码以处理日期范围或特定星期和/或星期几。

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)

【讨论】:

  • + 1 - 尽管我认为日历文件是个好主意,而且非常有用,但这是一个不错的简单解决方案。当然,这会排除某些日期(如果星期二是假期),但在其他情况下效果很好。
  • 这段代码的好处是它是动态的,并且由于它使用 DATEADD 函数,它会自动处理闰年、30 个月和 31 个月的日子等。它可以与“排除”结合使用' 表中存储的信息是年、月、周数和应该发生的星期几。我将添加一些代码来处理这种情况。
  • 如果假期是个问题,他应该只使用日历表,就像@Stuart 的回答一样。我不会混合这两个版本。
  • 这看起来像我要找的东西,感谢您抽出宝贵的时间!
【解决方案2】:

可能最好的解决方案是使用日历表。 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

【讨论】:

    【解决方案3】:

    使用@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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-19
      • 1970-01-01
      • 2014-10-30
      • 1970-01-01
      • 2018-11-07
      • 1970-01-01
      • 2017-10-24
      • 1970-01-01
      相关资源
      最近更新 更多