SQL Server Creating a rota with 4 teams, day and night shifts 8 week rotation

jm2pwxwz  于 2023-11-16  发布在  其他
关注(0)|答案(1)|浏览(97)

I need to create a lookup table to output by minute of the day of the team who are on duty. The shift times are 09:00 - 18:00 day shift and a night shift of 18:00 - 09:00. We have 4 Teams named Red Green Blue and White, the rota is on a recurring 8 week pattern. The pattern starts on 1st April 2023 2 Days Blue 2 Nights Green, 2 Days White 2 nights Blue, 2 days Red 2 nights White, 2 days Green 2 nights Red, then repeats starting with blue days again. The pattern never changes.
| Sample | Days | WeekDay | Shifts | Wholetime_Shift |
| ------------ | ------------ | ------------ | ------------ | ------------ |
| 2023-04-01 09:00:00.000 | 0 | Saturday | B/G | B |
| 2023-04-01 10:00:00.000 | 0 | Saturday | B/G | B |
| 2023-04-01 11:00:00.000 | 0 | Saturday | B/G | B |
| 2023-04-01 12:00:00.000 | 0 | Saturday | B/G | B |
| 2023-04-01 13:00:00.000 | 0 | Saturday | B/G | B |

The issue I have is that the case statement in the query is written based on a 2,2,3,2 pattern.

Any help would be most appreciated.

;WITH samples as (
select Cast( '04-01-2023 09:00' as DateTime ) as Sample
union all
/* Add hours up to the desired end date. */
select DateAdd( hour, 1, Sample )
  from Samples
 where Sample <= '2026-01-01'
), ExtendedSamples as (
/* Calculate the number of days since the beginning of the first shift on 1/1/2013. */
select Sample, DateDiff( hour, '04-01-2023 09:00', Sample ) / 24 as Days
  from Samples 
), Shifts as (
/* Calculate the shifts for each day. */
select *, case when (Days+1) % 9 in (1,2 ) then 'B/G' when (Days+1) % 9 in (3,4) then 'W/B' WHEN (Days+1) % 9 IN (5,6) THEN 'R/W' WHEN (Days+1) % 9 IN (7,8) THEN 'G/R' end as Shifts
  from ExtendedSamples 
) 
    
SELECT Sample, days, DATENAME(WEEKDAY,Sample) WeekDay,Shifts,
       case when DatePart( hour, Sample ) between 9 and 17 then Substring( Shifts, 1, 1 ) else Substring( Shifts, 3, 1 ) end as Wholetime_Shift
  FROM Shifts
option ( maxrecursion 0 );
wfauudbj

wfauudbj1#

Based on your description, the following may get you closer to where you need to be.

;WITH Dates AS (
/* Replace this with a calendar or tally table */ 
SELECT CAST(CAST(GETDATE() AS DATE) AS DATETIME) AS Date, DATEADD(DAY,(8*7)-1,CAST(GETDATE() AS DATE)) AS EndDate
UNION ALL
SELECT DATEADD(DAY,1,Date) AS Date, EndDate
  FROM Dates
WHERE EndDate > Date
), Teams AS (
SELECT 'B' AS TeamName, 0 AS Offset
UNION ALL
SELECT 'G' AS TeamName, 2 AS Offset
UNION ALL
SELECT 'R' AS TeamName, 4 AS Offset
UNION ALL
SELECT 'W' AS TeamName, 6 AS Offset
)

SELECT Date, MAX(BStart) AS BStart, MAX(BEnd) AS BEnd, MAX(GStart) AS GStart, MAX(GEnd) AS GEnd, MAX(RStart) AS RStart, MAX(REnd) AS REnd, MAX(WStart) AS WStart, MAX(WEnd) AS WEnd
  FROM (
        SELECT CAST(Date AS DATE) AS Date, CASE WHEN ((ROW_NUMBER() OVER (PARTITION BY TeamName ORDER BY Date)-1+Offset) % 8) BETWEEN 0 AND 1 THEN DATEADD(HOUR,9,Date)
                          WHEN ((ROW_NUMBER() OVER (PARTITION BY TeamName ORDER BY Date)-1+Offset) % 8) BETWEEN 2 AND 3 THEN DATEADD(HOUR,18,Date)
                          WHEN ((ROW_NUMBER() OVER (PARTITION BY TeamName ORDER BY Date)-1+Offset) % 8) BETWEEN 4 AND 7 THEN NULL
                      END AS ShiftStart,
                     CASE WHEN ((ROW_NUMBER() OVER (PARTITION BY TeamName ORDER BY Date)-1+Offset) % 8) BETWEEN 0 AND 1 THEN DATEADD(MILLISECOND,-3,DATEADD(HOUR,18,Date))
                          WHEN ((ROW_NUMBER() OVER (PARTITION BY TeamName ORDER BY Date)-1+Offset) % 8) BETWEEN 2 AND 3 THEN DATEADD(MILLISECOND,-3,DATEADD(HOUR,33,Date))
                          WHEN ((ROW_NUMBER() OVER (PARTITION BY TeamName ORDER BY Date)-1+Offset) % 8) BETWEEN 4 AND 7 THEN NULL
                      END AS ShiftEnd, TeamName + 'Start' AS TeamName1, TeamName + 'End' AS TeamName2                                                                                       
          FROM Dates
          CROSS APPLY Teams
       ) a
    PIVOT (
           MAX(ShiftStart) FOR TeamName1 IN ([BStart], [GStart], [RStart], [WStart])
          ) p1
    PIVOT (
           MAX(ShiftEnd) FOR TeamName2 IN ([BEnd], [GEnd], [REnd], [WEnd])
          ) p2
 GROUP BY Date;
DateBStartBEndGStartGEndRStartREndWStartWEnd
2023-10-262023-10-26 09:00:00.0002023-10-26 17:59:59.9972023-10-26 18:00:00.0002023-10-27 08:59:59.997
2023-10-272023-10-27 09:00:00.0002023-10-27 17:59:59.9972023-10-27 18:00:00.0002023-10-28 08:59:59.997
2023-10-282023-10-28 18:00:00.0002023-10-29 08:59:59.9972023-10-28 09:00:00.0002023-10-28 17:59:59.997
2023-10-292023-10-29 18:00:00.0002023-10-30 08:59:59.9972023-10-29 09:00:00.0002023-10-29 17:59:59.997
2023-10-302023-10-30 09:00:00.0002023-10-30 17:59:59.9972023-10-30 18:00:00.0002023-10-31 08:59:59.997
2023-10-312023-10-31 09:00:00.0002023-10-31 17:59:59.9972023-10-31 18:00:00.0002023-11-01 08:59:59.997
2023-11-012023-11-01 09:00:00.0002023-11-01 17:59:59.9972023-11-01 18:00:00.0002023-11-02 08:59:59.997
2023-11-022023-11-02 09:00:00.0002023-11-02 17:59:59.9972023-11-02 18:00:00.0002023-11-03 08:59:59.997
2023-11-032023-11-03 09:00:00.0002023-11-03 17:59:59.9972023-11-03 18:00:00.0002023-11-04 08:59:59.997
2023-11-042023-11-04 09:00:00.0002023-11-04 17:59:59.9972023-11-04 18:00:00.0002023-11-05 08:59:59.997
2023-11-052023-11-05 18:00:00.0002023-11-06 08:59:59.9972023-11-05 09:00:00.0002023-11-05 17:59:59.997
2023-11-062023-11-06 18:00:00.0002023-11-07 08:59:59.9972023-11-06 09:00:00.0002023-11-06 17:59:59.997
2023-11-072023-11-07 09:00:00.0002023-11-07 17:59:59.9972023-11-07 18:00:00.0002023-11-08 08:59:59.997
2023-11-082023-11-08 09:00:00.0002023-11-08 17:59:59.9972023-11-08 18:00:00.0002023-11-09 08:59:59.997
2023-11-092023-11-09 09:00:00.0002023-11-09 17:59:59.9972023-11-09 18:00:00.0002023-11-10 08:59:59.997
2023-11-102023-11-10 09:00:00.0002023-11-10 17:59:59.9972023-11-10 18:00:00.0002023-11-11 08:59:59.997
2023-11-112023-11-11 09:00:00.0002023-11-11 17:59:59.9972023-11-11 18:00:00.0002023-11-12 08:59:59.997
2023-11-122023-11-12 09:00:00.0002023-11-12 17:59:59.9972023-11-12 18:00:00.0002023-11-13 08:59:59.997
2023-11-132023-11-13 18:00:00.0002023-11-14 08:59:59.9972023-11-13 09:00:00.0002023-11-13 17:59:59.997
2023-11-142023-11-14 18:00:00.0002023-11-15 08:59:59.9972023-11-14 09:00:00.0002023-11-14 17:59:59.997
2023-11-152023-11-15 09:00:00.0002023-11-15 17:59:59.9972023-11-15 18:00:00.0002023-11-16 08:59:59.997
2023-11-162023-11-16 09:00:00.0002023-11-16 17:59:59.9972023-11-16 18:00:00.0002023-11-17 08:59:59.997
2023-11-172023-11-17 09:00:00.0002023-11-17 17:59:59.9972023-11-17 18:00:00.0002023-11-18 08:59:59.997
2023-11-182023-11-18 09:00:00.0002023-11-18 17:59:59.9972023-11-18 18:00:00.0002023-11-19 08:59:59.997
2023-11-192023-11-19 09:00:00.0002023-11-19 17:59:59.9972023-11-19 18:00:00.0002023-11-20 08:59:59.997
2023-11-202023-11-20 09:00:00.0002023-11-20 17:59:59.9972023-11-20 18:00:00.0002023-11-21 08:59:59.997
2023-11-212023-11-21 18:00:00.0002023-11-22 08:59:59.9972023-11-21 09:00:00.0002023-11-21 17:59:59.997
2023-11-222023-11-22 18:00:00.0002023-11-23 08:59:59.9972023-11-22 09:00:00.0002023-11-22 17:59:59.997
2023-11-232023-11-23 09:00:00.0002023-11-23 17:59:59.9972023-11-23 18:00:00.0002023-11-24 08:59:59.997
2023-11-242023-11-24 09:00:00.0002023-11-24 17:59:59.9972023-11-24 18:00:00.0002023-11-25 08:59:59.997
2023-11-252023-11-25 09:00:00.0002023-11-25 17:59:59.9972023-11-25 18:00:00.0002023-11-26 08:59:59.997
2023-11-262023-11-26 09:00:00.0002023-11-26 17:59:59.9972023-11-26 18:00:00.0002023-11-27 08:59:59.997
2023-11-272023-11-27 09:00:00.0002023-11-27 17:59:59.9972023-11-27 18:00:00.0002023-11-28 08:59:59.997
...........................

相关问题