0

我有一张员工日程表:

create table dbo.schedules
(agentID int,
dayID int,
shiftStart time, 
break1Start time, 
break1stop time,
lunchStart time, 
lunchStop time, 
break2Start time,
break2Stop time,
shiftEnd time,
offindicator bit
)

我想从 8:00 到 21:00 以 15 分钟为增量将可用代理的数量相加。

我该怎么做呢?

到目前为止,我有以下代码来评估它:

select 
sum(case when offindicator = 1 or @timeslot < shiftStart or  (@timeslot >= 
break1Start and @timeslot <break1stop) OR (@timeslot >= break2Start and @timeslot <
break2stop) OR @timeslot >= shiftend then 0 else 1 end) [onoff]
from dbo.schedules

...但现在我想要一个时隙列表和计数:

DayID | Timeslot | Count

1 |   8:00  |  15

1 |  8:15   |  10

1 |  8:30   |  20

1 |  8:45   |  10

等等

时间表表的一些示例数据:

(   215,    1,  NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   1   )
,(  215,    2,  '08:00',    '10:20',    '10:35',    '12:30',    '12:45',    '15:00',    '15:15',    '17:00',    0   )
,(  215,    3,  '08:00',    '10:20',    '10:35',    '12:30',    '12:45',    '15:00',    '15:15',    '17:00',    0   )
,(  215,    4,  '08:00',    '10:20',    '10:35',    '12:30',    '12:45',    '15:00',    '15:15',    '17:00',    0   )
,(  215,    5,  '08:00',    '10:20',    '10:35',    '12:30',    '12:45',    '15:00',    '15:15',    '17:00',    0   )
,(  215,    6,  '08:00',    '10:20',    '10:35',    '12:30',    '12:45',    '15:00',    '15:15',    '17:00',    0   )
,(  215,    7,  NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   1   )
4

1 回答 1

1

您可以通过获取您的CASE逻辑并在其中使用它来做到这一点JOIN,您需要一个驱动程序表来获取每个代理/天的每个时间段,因此cte

按 DayID/时间段:

WITH cte AS (SELECT DISTINCT agentID,DayID, CAST('08:00' AS TIME) 'Timeslot'
             FROM #schedules
             UNION 
             SELECT agentID,DayID,DATEADD(MINUTE,15,Timeslot)
             FROM cte
             WHERE Timeslot < '21:00')                     
SELECT b.DayID,Timeslot,SUM(CASE WHEN a.agentID IS NULL THEN 1 ELSE 0 END)
FROM #schedules a
RIGHT JOIN cte b
 ON a.agentID = b.agentID
   AND a.dayID = b.DayID
   AND (offindicator = 1 
        OR b.Timeslot < shiftStart 
        OR (b.Timeslot >= break1Start AND b.Timeslot <break1stop) 
        OR (b.Timeslot >= break2Start AND b.Timeslot <break2stop) 
        OR b.Timeslot >= shiftend)
GROUP BY b.DayID,b.Timeslot
ORDER BY b.Timeslot,b.DayID

或者您可以限制为特定的 DayID:

WITH cte AS (SELECT DISTINCT agentID,DayID, CAST('08:00' AS TIME) 'Timeslot'
             FROM #schedules
             UNION 
             SELECT agentID,DayID,DATEADD(MINUTE,15,Timeslot)
             FROM cte
             WHERE Timeslot < '21:00')                     
SELECT Timeslot,SUM(CASE WHEN a.agentID IS NULL THEN 1 ELSE 0 END)
FROM #schedules a
RIGHT JOIN cte b
 ON a.agentID = b.agentID
   AND a.dayID = b.DayID
   AND (offindicator = 1 
        OR b.Timeslot < shiftStart 
        OR (b.Timeslot >= break1Start AND b.Timeslot <break1stop) 
        OR (b.Timeslot >= break2Start AND b.Timeslot <break2stop) 
        OR b.Timeslot >= shiftend)
WHERE b.DayID = 1
GROUP BY b.Timeslot

注意:在防火墙ALL后面添加,防火墙阻止我发帖和彼此相邻。UNIONcteUNIONALL

于 2013-08-21T18:11:08.183 回答