创建日期范围列表

时间:2015-10-07 18:12:54

标签: sql sql-server sql-server-2008 date

我有一个开始日期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

我从这篇文章中找到了这个答案,但我不明白代码。

How to generate a range of dates in SQL Server

1 个答案:

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