我有一个开始日期01 / jan和结束日期22 / jan
我的员工连续工作5天,他们留在家中5天,在过去5天后再次开始工作。这5天被定义为我们公司的政策。
如何在SQL Server中的范围内获取工作日?喜欢这个
Bob从01 / jan开始工作 约翰从06年1月开始工作 亚历克斯从20岁开始工作
期间:1月从01 / jan到22 / jan
Bob 01 / jan - 05 / jan
Bob 11 / jan - 15 / jan
Bob 21 / jan - 22 / jan
John 06 / jan - 10 / jan
John 16 / jan - 20 / jan
Alex 20 / jan - 22 / jan
我从这篇文章中找到了这个答案,但我不明白代码。
答案 0 :(得分:1)
你走了!玩得开心。如果您需要更多帮助,请询问。
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
--This is a table that holds all the people who work for you and when they started
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
DECLARE @People TABLE
(
Name NVARCHAR(64),
FirstDate DATE
)
INSERT INTO @People
(
Name,
FirstDate
)
VALUES
('Bob','01/jan/2015'),
('Alex','20/jan/2015'),
('John','6/jan/2015')
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
--This is where the magic happens
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
--This is the date range you want the results for
DECLARE @StartDate DATE = '1/JAN/2015'
DECLARE @EndDate DATE = '22/JAN/2015'
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
--Using the above dates we can make a temporary table with all the dates for this date range
--This table could be a permanent table (with all reasonable dates in) if you wanted it to be,
--but for this example we will make it from scratch each time
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
DECLARE @DateTable TABLE (Date DATE)
DECLARE @Date DATE = @StartDate
--This is just a loop that inserts all the dates in the range
WHILE @Date <= @EndDate
BEGIN
INSERT INTO @DateTable(Date) VALUES (@Date)
SET @Date = DATEADD(D,1,@Date)
END
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
--Now this is the bit you will be interested in
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
SELECT Name, --Name
MIN(Date) AS [From], --First date
MAX(Date) AS [To] --Last date
FROM @People AS P --All people
CROSS JOIN @DateTable AS D --All dates
WHERE DATEDIFF(D,FirstDate,Date) / 5 % 2 = 0 --Turn dates into groups each with 5 dates in (/5) Then pick only the even groups (%2 = 0) so one on one off
AND FirstDate <= Date --The date must be after they started
GROUP BY Name,DATEDIFF(D,FirstDate,Date) / 5 --Group by each group so we can work out the first and last date of each group
ORDER BY Name --Make it look nice
如果您想要更改开启和关闭的天数,那么它会变得更复杂。
这是你怎么做的
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
--This is a table that holds all the people who work for you and when they started
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
DECLARE @People TABLE
(
Name NVARCHAR(64),
FirstDate DATE
)
INSERT INTO @People
(
Name,
FirstDate
)
VALUES
('Bob','01/jan/2015'),
('Alex','20/jan/2015'),
('John','6/jan/2015')
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
--This is where the magic happens
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
--This is the date range you want the results for
DECLARE @StartDate DATE = '1/JAN/2015'
DECLARE @EndDate DATE = '22/JAN/2015'
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
--Using the above dates we can make a temporary table with all the dates for this date range
--This table could be a permanent table (with all reasonable dates in) if you wanted it to be,
--but for this example we will make it from scratch each time
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
DECLARE @DateTable TABLE (Date DATE)
DECLARE @Date DATE = @StartDate
--This is just a loop that inserts all the dates in the range
WHILE @Date <= @EndDate
BEGIN
INSERT INTO @DateTable(Date) VALUES (@Date)
SET @Date = DATEADD(D,1,@Date)
END
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
--Used for changing the number of days each perosn works vs not works
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
DECLARE @DaysOn INT
DECLARE @DaysOff INT
SET @DaysOn = 5 --Days working
SET @DaysOff = 1 --Days not working
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
--Now this is the bit you will be interested in
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
SELECT Name,
MIN(Date) AS [From], --First date
MAX(Date) AS [To] --Last date
FROM
(
SELECT Name, --Name
Date, --Date
ROW_NUMBER() OVER (PARTITION BY Name,DATEDIFF(D,FirstDate,Date) / (@DaysOn + @DaysOff) ORDER BY Date) AS Day, --Day of cycle
DATEDIFF(D,FirstDate,Date) / (@DaysOn + @DaysOff) AS Cycle --Cycle
FROM @People AS P --All people
CROSS JOIN @DateTable AS D --All dates
WHERE FirstDate <= Date --The date must be after they started
) AS Cycle
WHERE Day <= @DaysOn --Only total up working days
GROUP BY Name,Cycle --For each person and cycle
ORDER BY Name --Make it looks nice