[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);
WorkDays : 为 开始日期(@startDate) 到 工作天数(@workDays) + 预加的工作天数(@bufferDays) 之间的日期。
HoldaysRange : 为 WorkDays 之间的所有假日(星期 六 日及节日)
所以 WorkDays 与 HoldaysRange LEFT JOIN 找出工作日,再加上流水号(seq)。
再用原本要的天数跟那个流水号比较就可以找出我们需要的工作日。
参考数据
计算日期之间的工作日
标签:找出,01,05,天数,WorkDay,日期,SQL,2015 来源: https://www.cnblogs.com/petewell/p/11490018.html