我正在处理应用程序的假期表,我必须根据该表中的假期列表找到下一个工作日。
如果输入是工作日,我们希望返回空白/ 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
答案 0 :(得分:0)
你可以试试这个:
--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 强>
答案 1 :(得分:0)
如果下面提到的代码有效,请告诉我。此代码首先制作一个日历表,然后从日期中排除星期六和星期日。
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'
答案 2 :(得分:0)
使用此结构设置假期表:
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
这是一个非常基本的第一个近似,但它应该有用。