【问题标题】:SQL Server : finding the nearest TuesdaySQL Server:查找最近的星期二
【发布时间】:2019-02-13 10:42:03
【问题描述】:

如何仅在 SQL Server 中查找给定日期前最近的星期二?

例如:今天是2018-09-09,结果应该是2018-09-04

【问题讨论】:

标签: sql sql-server sql-server-2008 sql-server-2005


【解决方案1】:

请试一试。

select 
case when datepart(dw,getdate()) =7 
or datepart(dw,getdate()) =6 
or  datepart(dw,getdate()) =5 
or datepart(dw,getdate()) =4  
then DATEADD(day, 3-datepart(dw,getdate()) , getdate())
else  DATEADD(day, -4-datepart(dw,getdate()) , getdate())
end;

【讨论】:

    【解决方案2】:

    显然我误读了这个问题,但我会把它留在这里以防其他人可能会发现它具有教育意义(它还演示了 DATEPART( dw, ... ) 结果如何因服务器而异,因此上述答案中的硬编码值可能会导致错误结果取决于环境) - 这将计算最接近指定星期几的日期(而问题是针对上一个星期二提出的,具体而言)...

    给你一个约会。您想找到最近的星期二,因此您首先需要确定给定日期代表一周中的哪一天。 Google "mssql day of week" 和 first hit 是您可以用来获取星期几的函数。它将采用整数格式,因此您需要引用 which numbers represents which days of the week

    结果将基于定义一周的第一天的@@DATEFIRST 的值(结果是从一个开始的索引),因此您需要调整目标星期几的值以与服务器的@@DATEFIRST 值。您可以通过从7 中减去@@DATEFIRST 来做到这一点,添加目标星期几值(1:星期一到 7:星期日),将结果与 7 取模并添加 1 以保持从一开始索引:

    ( 7 - @@DATEFIRST + @targetDayOfWeek ) % 7 + 1
    

    一旦您知道您的目标日期是星期几以及星期二代表的数字,您就可以计算天数差。如果幅度大于 3,则通过加减 7 进行调整以适应范围 [-3, 3]。

    create function dbo.CalculateClosestDayOfWeekDate
    (
        @fromDate DATETIME,
        @targetDayOfWeek int -- 1: Monday ... 7: Sunday
    )
    returns DATETIME
    as
    begin
        -- AdjustedTargetDayOfWeek: ( 7 - @@DATEFIRST + @targetDayOfWeek ) % 7 + 1
        -- FromDateDayOfWeek: DATEPART( dw, @fromDate )
        -- DayOfWeekDiff = AdjustedTargetDayOfWeek - FromDateDayOfWeek
    
        declare @daysToAdd int
        set @daysToAdd = ( ( 7 - @@DATEFIRST + @targetDayOfWeek ) % 7 + 1 ) - DATEPART( dw, @fromDate )
    
        -- if the nearest previous day-of-week is all that's wanted,
        --   replace the below block with `if( 0 < @daysToAdd)`
        --   and subtract 7 from @daysToAdd if true
        if( 3 < ABS( @daysToAdd ) ) -- if magnitude greater than 3
        begin
            if( 3 < @daysToAdd ) -- if positive, subtract 7
            begin
                set @daysToAdd = @daysToAdd - 7
            end
            else -- negative, so add 7
            begin
                set @daysToAdd = @daysToAdd + 7
            end
        end
    
        return DATEADD( day, @daysToAdd, @fromDate )
    end
    go
    
    declare @testData table
    (
        FromDate dateTime,
        TargetDayOfWeek int
    )
    
    insert @testData values ( '2018-09-08', 2 ) -- target Tuesday from a Saturday
    insert @testData values ( '2018-09-08', 3 ) -- target Wednesday from a Saturday
    insert @testData values ( '2018-09-09', 3 ) -- target Wednesday from a Sunday
    insert @testData values ( '2018-09-09', 4 ) -- target Thursday from a Sunday
    insert @testData values ( '2018-09-10', 4 ) -- target Thursday from a Monday
    insert @testData values ( '2018-09-10', 5 ) -- target Friday from a Monday
    
    select
        td.FromDate
        , td.TargetDayOfWeek
        , dbo.CalculateClosestDayOfWeekDate( td.FromDate, td.TargetDayOfWeek ) ResultingDate
    from
        @testData td
    

    结果:

    【讨论】:

      【解决方案3】:

      使用case whendatepart 函数并有条件地查找最近的星期二

         select case datepart(dw,getdate()) when 7 then DATEADD(day, -4, getdate()) 
      when 1 then DATEADD(day, -5, getdate())
      when 2 then DATEADD(day, -6, getdate())
      when 3 then DATEADD(day, -7, getdate())
      when 4  then DATEADD(day, -1, getdate())
      when 5  then DATEADD(day, -2, getdate())
      when 6  then DATEADD(day, -3, getdate())
      else getdate() end;
      

      【讨论】:

      • 硬编码用于星期二,这是一个通用解决方案,其中目标星期几是更好的解决方案
      • @Moho 阅读问题 op 寻找从任何给定日期起最近的星期二的答案,并在您描述拒绝投票的原因时感谢您的拒绝投票
      • 嗨,Akh,您的回答很好,但在下周二给出。请参考:rextester.com/REKHK7643
      • @BarbarosÖzhan 谢谢我认为 op 想要给定最近的将来或以前的日期,但再次感谢我只编辑以前的日期
      • DATEPART( dw, ... ) 结果基于@@DATEFIRST 的值;不应该假设7 是本周的开始。通过( 7 - @@DATEFIRST + @targetDayOfWeek ) % 7 + 1 调整,其中@targetDayOfWeek2 周二
      猜你喜欢
      • 1970-01-01
      • 2012-12-10
      • 1970-01-01
      • 1970-01-01
      • 2021-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多