从SQL表中查找下一个工作日

从SQL表中查找下一个工作日,sql,sql-server,sql-server-2008,sql-server-2008-r2,Sql,Sql Server,Sql Server 2008,Sql Server 2008 R2,我正在处理一个申请的假期表,我必须根据该表中的假期列表找到下一个工作日 如果输入是一个工作日,我们希望返回一个空白/NULL,但是如果是假日,我们希望返回下一个工作日 我的假日表包含以下示例数据。 第一个日期列是startdate,第二个是enddate。而不是连续两个假日使用startdate和enddate。客户端已经创建了两个单独的行 现在,我必须编写一个select查询,它将根据该样本数据给出下一个工作日 假设我将“2016-04-20 00:00:00.000”作为条件日期,则查询应返

我正在处理一个申请的假期表,我必须根据该表中的假期列表找到下一个工作日

如果输入是一个工作日,我们希望返回一个空白/NULL,但是如果是假日,我们希望返回下一个工作日

我的假日表包含以下示例数据。 第一个日期列是startdate,第二个是enddate。而不是连续两个假日使用startdate和enddate。客户端已经创建了两个单独的行

现在,我必须编写一个select查询,它将根据该样本数据给出下一个工作日

假设我将“2016-04-20 00:00:00.000”作为条件日期,则查询应返回“2016-04-22 00:00:00.000”作为工作日期,并且连续有两个假期

2016    2016-04-20 00:00:00.000 2016-04-20 00:00:00.000 Test
2016    2016-04-21 00:00:00.000 2016-04-21 00:00:00.000 Test2
2016    2016-04-28 00:00:00.000 2016-04-28 00:00:00.000 Test3
您可以尝试以下方法:

--create table holidays(y int, ds datetime, de datetime, hname varchar(10));
--insert into holidays  values
--(2016,'2016-04-20 00:00:00.000','2016-04-20 00:00:00.000','Test'),
--(2016,'2016-04-21 00:00:00.000','2016-04-21 00:00:00.000','Test2'),
--(2016,'2016-04-28 00:00:00.000','2016-04-28 00:00:00.000','Test3'),
--(2016,'2016-04-22 00:00:00.000','2016-04-22 00:00:00.000','Test4')
CREATE FUNCTION dbo.getNextDate(@dateToCheck datetime) RETURNS Datetime
AS
BEGIN

 RETURN(
select top 1 dateadd(d,1,de)  from 

(select y,
  MIN(ds) as ds, 
  MAX(ds) as de
from 
 (
  Select 
   *, 
   ROW_NUMBER() OVER(ORDER BY ds asc) as ranking 
   from holidays
 ) t  
 group by y,(CAST(ds AS INT)-Ranking)
)t
where @dateToCheck BETWEEN ds AND de
)
END
测试时:

SELECT dbo.getNextDate('2016-04-23 00:00:00.000')-- returns NULL
SELECT dbo.getNextDate('2016-04-21 00:00:00.000')-- returns 2016-04-23 00:00:00.000

您可以尝试以下方法:

--create table holidays(y int, ds datetime, de datetime, hname varchar(10));
--insert into holidays  values
--(2016,'2016-04-20 00:00:00.000','2016-04-20 00:00:00.000','Test'),
--(2016,'2016-04-21 00:00:00.000','2016-04-21 00:00:00.000','Test2'),
--(2016,'2016-04-28 00:00:00.000','2016-04-28 00:00:00.000','Test3'),
--(2016,'2016-04-22 00:00:00.000','2016-04-22 00:00:00.000','Test4')
CREATE FUNCTION dbo.getNextDate(@dateToCheck datetime) RETURNS Datetime
AS
BEGIN

 RETURN(
select top 1 dateadd(d,1,de)  from 

(select y,
  MIN(ds) as ds, 
  MAX(ds) as de
from 
 (
  Select 
   *, 
   ROW_NUMBER() OVER(ORDER BY ds asc) as ranking 
   from holidays
 ) t  
 group by y,(CAST(ds AS INT)-Ranking)
)t
where @dateToCheck BETWEEN ds AND de
)
END
测试时:

SELECT dbo.getNextDate('2016-04-23 00:00:00.000')-- returns NULL
SELECT dbo.getNextDate('2016-04-21 00:00:00.000')-- returns 2016-04-23 00:00:00.000

让我知道下面提到的代码是否有效。此代码首先生成日历表,然后从日期中排除周六和周日

declare @mn date = (select min(yourdate) from table)
select top 1 a.caldate
from
(
select dateadd(dd,row_number() over (order by (select 1)) - 1,@mn) as caldate
from sys.all_objects
) as a
where a.caldate not in (select cast(yourdate as date) as yourdate from TableA) and datename(dw,a.caldate) not in ('Saturday','Sunday') and a.caldate >= '2016-04-20'

让我知道下面提到的代码是否有效。此代码首先生成一个日历表,然后从日期中排除周六和周日

declare @mn date = (select min(yourdate) from table)
select top 1 a.caldate
from
(
select dateadd(dd,row_number() over (order by (select 1)) - 1,@mn) as caldate
from sys.all_objects
) as a
where a.caldate not in (select cast(yourdate as date) as yourdate from TableA) and datename(dw,a.caldate) not in ('Saturday','Sunday') and a.caldate >= '2016-04-20'

使用此结构支撑假日表:

CREATE TABLE holidays (
    [year] int,
    [ds] datetime,
    [de] datetime,
    [description] nvarchar(50)
)
您可以创建一个函数,该函数遍历日期,直到找到正确的日期为止

CREATE FUNCTION dbo.getNextDate(@dateToCheck datetime) RETURNS Datetime
AS
BEGIN
    DECLARE @tempDate datetime
    SET @tempDate=DATEADD(day,1,@dateToCheck)
    WHILE EXISTS(SELECT * FROM holidays WHERE @tempDate BETWEEN ds AND de)
    BEGIN
        SET @tempDate=DATEADD(day,1,@tempDate)
    END

    RETURN @tempDate
END

这是一个非常基本的第一个近似值,但它应该会起作用。

使用此结构支持假日表:

CREATE TABLE holidays (
    [year] int,
    [ds] datetime,
    [de] datetime,
    [description] nvarchar(50)
)
您可以创建一个函数,该函数遍历日期,直到找到正确的日期为止

CREATE FUNCTION dbo.getNextDate(@dateToCheck datetime) RETURNS Datetime
AS
BEGIN
    DECLARE @tempDate datetime
    SET @tempDate=DATEADD(day,1,@dateToCheck)
    WHILE EXISTS(SELECT * FROM holidays WHERE @tempDate BETWEEN ds AND de)
    BEGIN
        SET @tempDate=DATEADD(day,1,@tempDate)
    END

    RETURN @tempDate
END

这是一个非常基本的第一个近似值,但它应该会起作用。

如果您通过了
'2016-04-19 00:00:00.000'
?您是否仍希望
'2016-04-22 00:00:00.000'
?否查询将检查日期是否在假日列表范围内。如果不在假日列表范围内,则可以返回空白。如“2016-04-19 00:00:00.000”的情况。因此,如果您的输入是工作日,您希望返回空白,但如果是假日,您希望返回下一个工作日?是的,这是实际要求。为什么假日表有两个日期列?如果您通过
'2016-04-19 00:00:00.000'
?您是否仍希望
'2016-04-22 00:00:00.000'
?否查询将检查日期是否在假日列表范围内。如果不在假日列表范围内,则可以返回空白。如“2016-04-19 00:00:00.000”的情况。因此,如果您的输入是工作日,您希望返回空白,但如果是假日,您希望返回下一个工作日?是的,这是实际要求。为什么假日表有两个日期列?