首页 文章

如何使用sql server在当前工作日的一周内获得上一个工作日

提问于
浏览
10

我有一个ssis包,在工作日(周一至周五)运行 . 如果我在星期二,背景(DB)收到文件,它需要上一个工作日日期并进行一些交易 . 如果我在星期五运行这个工作,它必须获取星期一的日期并处理交易 .

我使用以下查询来获取以前的营业日期

Select Convert(varchar(50), Position_ID) as Position_ID,
       TransAmount_Base,
       Insert_Date as InsertDate
  from tblsample
 Where AsOfdate = Dateadd(dd, -1, Convert(datetime, Convert(varchar(10), '03/28/2012', 101), 120))
Order By Position_ID

如果我执行此查询,我将得到昨天Transactios的结果 . 如果我在星期一运行相同的查询,它必须获取星期五的交易而不是星期日 .

7 回答

  • 1

    感谢上面的提示,我对查询略有不同,因为我的用户需要上一个营业日期的所有值 . 例如,今天是星期一,所以他需要在上周五午夜到周六午夜之间的所有事情 . 我使用上面的组合和“之间”这样做,只要有人感兴趣 . 我不是一个庞大的技术人员 .

    -- Declare a variable for the start and end dates.
    declare @StartDate as datetime 
    declare @EndDate as datetime 
    
    SELECT  @StartDate = DATEADD(DAY, CASE DATENAME(WEEKDAY, GETDATE()) 
    WHEN 'Sunday' THEN -2 
    WHEN 'Monday' THEN -3 
        ELSE -1 END, DATEDIFF(DAY, 0, GETDATE()))
    select @EndDate = @StartDate + 1 
    select @StartDate , @EndDate 
    -- Later on in the query use "between"
    and mydate between @StartDate and @EndDate
    
  • 36

    那怎么样:

    declare @dt datetime='1 dec 2012'
    
    select case when 8-@@DATEFIRST=DATEPART(dw,@dt)  
                then DATEADD(d,-2,@dt)  
            when (9-@@DATEFIRST)%7=DATEPART(dw,@dt)%7  
                then DATEADD(d,-3,@dt)  
            else DATEADD(d,-1,@dt)  
        end
    
  • 0

    找到前一个工作日的最简单的解决方案是使用带有名为 IsBusinessDay 的列的calendar table或类似的东西 . 您的查询是这样的:

    select max(BaseDate)
    from dbo.Calendar c
    where c.IsBusinessDay = 0x1 and c.BaseDate < @InputDate
    

    使用函数的问题在于,当(因为)您必须出于任何原因(国家法定假日等)创建异常时,代码很快就变得无法维护;与表,你只需 UPDATE 一个值 . 表格还可以更轻松地回答"how many business days are there between dates X and Y"等问题,这些问题在报告任务中非常常见 .

  • 0
    SELECT  DATEADD(DAY, CASE DATENAME(WEEKDAY, GETDATE()) 
                            WHEN 'Sunday' THEN -2 
                            WHEN 'Monday' THEN -3 
                            ELSE -1 END, DATEDIFF(DAY, 0, GETDATE()))
    

    我更喜欢使用 DATENAME 这样的事情而不是 DATEPART 因为它不需要设置 DATEFIRST 并确保本地机器上时间/日期设置的变化不会影响结果 . 最后 DATEDIFF(DAY, 0, GETDATE()) 将删除 GETDATE() 的时间部分,无需转换为varchar(慢得多) .


    EDIT (almost 2 years on)

    这个答案在我职业生涯的早期就已经很早了,每次上调都会让我很烦,因为我不再同意使用DATENAME的情绪 .

    一个更加严重的解决方案是:

    SELECT  DATEADD(DAY, CASE (DATEPART(WEEKDAY, GETDATE()) + @@DATEFIRST) % 7 
                            WHEN 1 THEN -2 
                            WHEN 2 THEN -3 
                            ELSE -1 
                        END, DATEDIFF(DAY, 0, GETDATE()));
    

    这适用于所有语言和DATEFIRST设置 .

  • 1

    您可以轻松地将其作为函数调用,添加第二个参数以将GetDate()替换为您想要的任何日期 . 如果您更改GetDate(),它将适用于任何日期范围内的任何一天 . 如果星期几是输入日期(GetDate()),则不会更改日期

    Declare @DayOfWeek As Integer = 2   -- Monday
    
    Select DateAdd(Day, ((DatePart(dw,GetDate()) + (7 - @DayOfWeek)) * -1) % 7, Convert(Date,GetDate()))
    
  • 3
    select  
      dateadd(dd, 
                 case DATEPART(dw, getdate()) 
                 when 1 
                 then -2 
                 when 2 
                 then -3 
                 else -1 
             end, GETDATE())
    
  • 0

    更优雅:

    select DATEADD(DAY, 
    CASE when datepart (dw,Getdate()) < 3 then datepart (dw,Getdate()) * -1 + -1 ELSE -1 END,
    cast(GETDATE() as date))
    

相关问题