数据库
首页 > 数据库> > [SQL]开始日期加上工作天数,找出工作日

[SQL]开始日期加上工作天数,找出工作日

作者:互联网

如果有开始日期,再给你一个工作天数,是否可以找出这些工作日呢?


如果有开始日期,再给你一个工作天数,是否可以找出这些工作日呢?

我们可以依“计算日期之间的工作日”的方式,将工作天数再加上节日及星期六、日。

以开始日期为 2015/05/01 ,工作天数为 5 天

05/01 为 劳动节

05/02, 05/03 为星期六、日

所以要加上 3 天

就会是 2015/05/01 ~ 2015/05/08

这样子就可以了吗???

如果 2015/05/08 是节日的话,那天数还要再加 1 天。

可是,前面我顶多只会先算到 2015/05/01 ~ 2015/05/05 之间的假日。

所以还要再看前面多出来的天数加进去后,再看有没有假日,然后再加,再Check,再加 ..... 一直下去

我们可以用另一个做法,就是多取几天出来,找出工作日,然后再依天数来取得那些工作日。

把逻辑列清楚后,我们就可以开始来写SQL了,如下,

以开始日期为 2015/05/01 ,工作天数为 5 天

05/01 为 劳动节

05/02, 05/03 为星期六、日

05/08 为 临时节日

所以工作日会是 5/4 ~ 5/7 及 5/11


/* 数据准备 
--假日档
-- Drop TABLE Holidays;
CREATE TABLE Holidays
(
Id INT IDENTITY,
HolidayDate DATE,
HolidayName NVARCHAR(32) 
)
GO
INSERT INTO dbo.Holidays
        (HolidayDate, HolidayName )
VALUES  ('2015/05/01', N'劳动节');
INSERT INTO dbo.Holidays
        (HolidayDate, HolidayName )
VALUES  ('2015/05/08', N'临时节日');
*/

DECLARE @startDate  DATETIME,
@workDays INT, @bufferDays INT;
SELECT @startDate = '2015/05/1'  -- 开始日期
,@workDays = 5 -- 工作天数为 5   
,@bufferDays = 30 -- 计算后面的 Buffer 的天数

;WITH WorkDays -- 所有日期
AS(
	SELECT @startDate AS WorkDay, @workDays + @bufferDays AS DiffDays 
	UNION ALL
	SELECT DATEADD(dd, 1, WorkDay),DiffDays -1
	FROM WorkDays wd
	WHERE DiffDays > 1
), HoldaysRange --星期 六 日及节日
AS (
SELECT *
FROM WorkDays wds
WHERE DATEPART(dw, wds.WorkDay ) IN (1, 7)
	OR EXISTS (SELECT * FROM dbo.Holidays h WHERE h.HolidayDate = wds.WorkDay)
), WorkDaysRange 
AS (
SELECT wd.*, ROW_NUMBER() OVER(ORDER BY wd.WorkDay) AS seq
FROM WorkDays wd
LEFT JOIN HoldaysRange hr
ON wd.WorkDay = hr.WorkDay
WHERE hr.WorkDay IS NULL
) 
SELECT * 
FROM WorkDaysRange wr
WHERE wr.seq <= @workDays
OPTION (MAXRECURSION 0);

image

WorkDays : 为 开始日期(@startDate) 到 工作天数(@workDays) + 预加的工作天数(@bufferDays) 之间的日期。

HoldaysRange : 为 WorkDays 之间的所有假日(星期 六 日及节日)

所以 WorkDays 与 HoldaysRange LEFT JOIN 找出工作日,再加上流水号(seq)。

再用原本要的天数跟那个流水号比较就可以找出我们需要的工作日。

参考数据

计算日期之间的工作日

原文:大专栏  [SQL]开始日期加上工作天数,找出工作日


标签:找出,01,05,天数,WorkDay,日期,SQL,2015
来源: https://www.cnblogs.com/petewell/p/11490018.html