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

Posted

技术标签:

【中文标题】从 SQL 表中查找下一个工作日【英文标题】:Finding the next working day from SQL table 【发布时间】:2016-04-20 09:21:56 【问题描述】:

我正在处理一个应用程序的假期表,我必须根据该表中的假期列表找到下一个工作日。

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

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

现在我必须编写一个选择查询,它将根据该示例数据给出下一个工作日。

假设如果我传递 '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

【问题讨论】:

如果你通过'2016-04-19 00:00:00.000'怎么办?你还会期待'2016-04-22 00:00:00.000'吗? 否查询是否会检查日期是否在假期列表范围内。如果它不在假期列表范围内,则可以返回空白。如'2016-04-19 00 :00:00.000'. 那么,如果你输入的是工作日,你期望返回一个空白,但是如果是假期,你期望下一个工作日返回? 是的 Raj,这是实际要求。 为什么你的假期表有两个日期列? 【参考方案1】:

你可以试试这个:

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

SQL demo link

【讨论】:

【参考方案2】:

如果下面提到的代码有效,请告诉我。此代码首先创建一个日历表,然后从日期中排除周六和周日。

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'

【讨论】:

【参考方案3】:

假设一个假期表具有这种结构:

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

这是一个非常基本的第一近似值,但它应该可以工作。

【讨论】:

以上是关于从 SQL 表中查找下一个工作日的主要内容,如果未能解决你的问题,请参考以下文章

MAC VBA尝试从每个工作表中剪切一个单元格并粘贴到下一个空单元格中的另一张表中

Excel 公式在工作簿中查找下一个工作表

从 SQL Server DB 更新单独工作表中的数据后自动刷新 Excel 2007 数据透视表

如何使用字典对象从工作表中的重复标题中查找和组合数据

Excel - UDF 函数,用于根据条件从多个工作表中获取 SUM 值

在多对多 SQL 表中查找数据关系或图形