Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用sql server获取一周中的上一个工作日与当前工作日的工作日_Sql_Sql Server - Fatal编程技术网

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

如何使用sql server获取一周中的上一个工作日与当前工作日的工作日,sql,sql-server,Sql,Sql Server,我有一个ssis包,在工作日(周一至周五)运行。如果我在星期二收到文件,背景(DB),它会占用上一个工作日的日期并进行一些事务处理。如果我在星期五运行作业,它必须获取星期一日期并处理事务 我已使用下面的查询获取以前的业务日期 Select Convert(varchar(50), Position_ID) as Position_ID, TransAmount_Base, Insert_Date as InsertDate from tblsample Wher

我有一个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的结果。如果我在周一运行相同的查询,它必须获取周五的事务,而不是周日

select  
  dateadd(dd, 
             case DATEPART(dw, getdate()) 
             when 1 
             then -2 
             when 2 
             then -3 
             else -1 
         end, GETDATE())
我更喜欢在
DATEPART
上使用
DATENAME
,因为它不需要设置
DATEFIRST
,并确保本地机器上的时间/日期设置变化不会影响结果。最后,
DATEDIFF(DAY,0,GETDATE())
将删除
GETDATE()
的时间部分,不再需要转换为varchar(速度慢得多)


编辑(近两年)

这个答案在我SO职业生涯的早期就出现了,每次都让我恼火,因为我不再同意使用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设置。

查找前一个工作日的最简单解决方案是将a与名为
IsBusinessDay
或类似内容的列一起使用。您的查询如下所示:

select max(BaseDate)
from dbo.Calendar c
where c.IsBusinessDay = 0x1 and c.BaseDate < @InputDate
选择最大值(基准日期)
来自dbo.Calendar c
其中c.IsBusinessDay=0x1和c.BaseDate<@InputDate
使用函数的问题是,当(而不是如果)由于任何原因(国家假日等)必须创建异常时,代码很快变得无法维护;使用该表,您只需更新一个值。表格也使回答诸如“X日和Y日之间有多少工作日”之类的问题变得更加容易,这在报告任务中非常常见。

那么:

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

感谢上面的提示,我的查询有一个小小的变化,我的用户需要上一个业务日期的所有值。例如,今天是星期一,所以从上周五午夜到周六午夜,他需要所有东西。如果有人感兴趣的话,我使用上面和“中间”的组合来实现这一点。我不是一个技术高超的人

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

您可以很容易地将其作为一个函数调用,添加第二个参数,用所需的任何日期替换GetDate()。 如果更改GetDate(),它将在一周中的任何一天、任何日期范围内工作。 如果星期几是输入日期,则不会更改日期(GetDate())

更优雅:

select DATEADD(DAY, 
CASE when datepart (dw,Getdate()) < 3 then datepart (dw,Getdate()) * -1 + -1 ELSE -1 END,
cast(GETDATE() as date))
选择日期添加(日期,
当datepart(dw,Getdate())小于3,然后datepart(dw,Getdate())*-1+-1 ELSE-1 END时,
强制转换(GETDATE()作为日期))

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

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

使用
DATEPART(dw…
在不知道
DATEFIRST
设置的情况下。不要这样做。使用
DATENAME
避免需要知道
DATEFIRST
,却忽略了它的语言特定性?这是一个很好的观点。但是,我遇到的问题是DATEFIRST冲突的场景比语言冲突的场景更多flicts一直是一个问题。例如,如果要在数据库中创建自定义项,则无法在自定义项中定义日期优先,您将依赖调用函数的查询来设置正确的日期优先(或不设置其他日期优先),用户更可能需要先设置不同的日期,而不是设置不同的语言(以我的经验).为了进一步说明,我曾在一家公司工作,其中书面销售的佣金周从周三到周二,电话销售的佣金周从周五到周四,我们可以使用相同的查询,通过相应地设置datefirst来报告这一点,这将使用DATEPART(DAY,[日期])识别周末是无用的。这就是为什么我更喜欢使用datename。我不主张它是完美的。嗨,我通过从AsofDate列中选择最长日期对问题进行排序。因此每次它都不需要检查前一个工作日是星期五还是其他任何一天。选择Convert(varchar(50),Position_ID)作为Position_ID,TransAmount_Base,Insert_Date作为InsertDate from BLE..tblIncome_Staging其中AsOfdate=(从tblsample中选择max(AsOfdate))按Position_ID排序这是我实现的逻辑。为什么需要在末尾写入DATEDIFF(DAY,0,GETDATE()),而不是GETDATE()?
select DATEADD(DAY, 
CASE when datepart (dw,Getdate()) < 3 then datepart (dw,Getdate()) * -1 + -1 ELSE -1 END,
cast(GETDATE() as date))
-- =============================================
-- 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