我有一组数据
Agent Rank START STOP CODE
Joey 52 11:30 11:45 BRK_Break1
Joey 53 17:30 17:45 BRK_Break2
Joey 57 14:15 15:15 BRK_Lunch
Joey 152 09:40 19:00 CONT_Shift
这是整个数据中的人“状态”。逻辑需要是每个“时间段”有一行,所以它根据等级创建一个连续的“时间轴”(更低=更高的优先级),所以它看起来像下面
Agent Start Stop Code
Joey 09:40 11:30 CONT_Shift
Joey 11:30 11:45 BRK_Break1
Joey 11:45 14:15 CONT_Shift
Joey 14:15 15:15 BRK_Lunch
Joey 15:15 17:30 CONT_Shift
Joey 17:30 17:45 BRK_Break2
Joey 17:45 19:00 CONT_Shift
任何想法如何实现这一目标?理想情况下,我想限制使用临时表,并通过CTE或可能是一些自联接但不确定从哪里开始执行此操作?
答案 0 :(得分:2)
这是一个非常好的问题,回答它很难。首先,我等待其他人解决,但由于没有发生,我试了一下,发现了一个错误并再次尝试。
它不漂亮,但似乎sql中没有支持该问题的功能。所以sql非常复杂。如果其他人提出了一个不同的更好的解决方案,我将是第一个给它加分的人。
declare @t table (name varchar(10), rank int, start datetime, stop datetime, code varchar(12))
insert @t values ('Joey', 52, '2011-06-21 11:30', '2011-06-21 11:45', 'BRK_Break1')
insert @t values ('Joey', 53, '2011-06-21 17:30', '2011-06-21 17:45', 'BRK_Break2')
insert @t values ('Joey', 57, '2011-06-21 14:15', '2011-06-21 15:15', 'BRK_Lunch')
insert @t values ('Joey',152, '2011-06-21 09:40', '2011-06-21 19:00', 'CONT_Shift')
insert @t values ('Joey',152, '2011-06-22 09:40', '2011-06-22 19:00', 'CONT_Shift')
;with aa as
(
select name, rank, start, 'b' action, code from @t
union all
select name, rank, stop, 'e', code from @t
)
select * from (
select name,start,
(select min(start) from aa where start > a.start and a.name = name) stop,
(select code from (select rank() OVER (ORDER BY rank) as rank, code from @t where dateadd(second, 1, a.start) between start and stop and name = a.name) c where rank = 1) code
from aa a
where not exists (select 1 from @t where a.start between start and stop and a.rank > rank and a.name = name)
and exists (select 1 from @t where a.start between start and stop and a.name = name)
) d
where code is not null and
name = 'Joey'
order by start