如何使用sql server获取当前工作日的一周中的上一个工作日

时间:2012-03-29 09:38:14

标签: sql sql-server

我有一个在工作日(周一至周五)运行的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的结果。如果我在星期一运行相同的查询,它必须获取星期五的交易而不是星期日。

8 个答案:

答案 0 :(得分:45)

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(慢得多)。


编辑(差不多2年)

这个答案在我职业生涯的早期就已经很早了,每次上调都会让我感到懊恼,因为我不再同意使用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 :(得分:3)

那怎么样:

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

答案 2 :(得分:1)

查找上一个工作日的最简单方法是使用calendar table,其中包含名为IsBusinessDay的列或类似内容。您的查询是这样的:

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

使用函数的问题在于,当(因为)您必须因任何原因(国家法定假日等)创建异常时,代码很快就会变得不可维护;使用该表,您只需UPDATE一个值。表格还可以更轻松地回答诸如“日期X和Y之间有多少个工作日”之类的问题,这在报告任务中非常常见。

答案 3 :(得分:1)

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

,则不会更改日期
Declare @DayOfWeek As Integer = 2   -- Monday

Select DateAdd(Day, ((DatePart(dw,GetDate()) + (7 - @DayOfWeek)) * -1) % 7, Convert(Date,GetDate()))

答案 4 :(得分:1)

此函数返回上一个工作日,并考虑到假期和周末。您将需要创建一个简单的假期表。

-- =============================================
-- Author:      Dale Kilian
-- Create date: 2019-04-29
-- Description: recursive function returns last work day for weekends and 
-- holidays
-- =============================================
ALTER FUNCTION dbo.fnGetWorkWeekday
(
    @theDate DATE
)
RETURNS DATE
AS
BEGIN

DECLARE @importDate DATE = @theDate
DECLARE @returnDate DATE
--Holidays
IF EXISTS(SELECT 1 FROM dbo.Holidays WHERE isDeleted = 0 AND @theDate = Holiday_Date)
BEGIN
SET @importDate = DATEADD(DAY,-1,@theDate);
SET @importDate = (SELECT dbo.fnGetWorkWeekday(@importDate))
END
--Satruday
IF(DATEPART(WEEKDAY,@theDate) = 7)
BEGIN
    SET @importDate = DATEADD(DAY,-1,@theDate);
    SET @importDate = (SELECT dbo.fnGetWorkWeekday(@importDate))
END
--Sunday
IF(DATEPART(WEEKDAY,@theDate) = 1)
BEGIN
    SET @importDate = DATEADD(DAY,-2,@theDate);
    SET @importDate = (SELECT dbo.fnGetWorkWeekday(@importDate))
END


RETURN @importDate;
END
GO

答案 5 :(得分:0)

select  
  dateadd(dd, 
             case DATEPART(dw, getdate()) 
             when 1 
             then -2 
             when 2 
             then -3 
             else -1 
         end, GETDATE())

答案 6 :(得分:0)

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

-- 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

答案 7 :(得分:0)

更优雅:

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