查询将时间段拆分为较小的段

时间:2015-12-17 12:00:04

标签: sql sql-server sql-server-2008 sql-server-2012

我有以下几点:

1-员工时间表

declare @table table (EmployeeId int,StartOn datetime,EndOn datetime)
insert into @table(EmployeeId,StartOn,EndOn)
values(1,'15 Dec 2015 09:00','15 Dec 2015 17:00')

2-休息时间

declare @break table(EmployeeId int,StartOn datetime,EndOn datetime)
insert into @break(EmployeeId,StartOn,EndOn)
values(1,'15 Dec 2015 09:45','15 Dec 2015 10:10')
insert into @break(EmployeeId,StartOn,EndOn)
values(1,'15 Dec 2015 11:30','15 Dec 2015 12:00')

3 - 出局应该是

EmployeeId  Date          From      To     Type
1          '15 Dec 2015'  '09:00'  '09:45'  'F' -- Working
1          '15 Dec 2015'  '09:45'  '09:10'  'B' -- Break
1          '15 Dec 2015'  '10:10'  '11:30'  'F' -- Working
1          '15 Dec 2015'  '11:30'  '12:00'  'B' -- Break
1          '15 Dec 2015'  '12:00'  '17:00'  'F' -- Working

目前我能够将此结果作为游标获得,我想提高性能并将此结果从游标转换为查询。

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

我认为这样做会:

http://www.lapenderiedechloe.com/
http://www.estelleblogmode.com/

你应该彻底测试它,还有性能。我不知道这实际上是否比你的光标更快。

答案 1 :(得分:1)

根据Gordon Linoff的推荐

这里我得到了什么

;with counting as (
    select EmployeeId,count(*) as Number
    from @break
    group by EmployeeId
), combine as (
    select t.EmployeeId,t.StartOn,t.EndOn,b.StartOn as TimeStart,b.EndOn as TimeEnd,c.Number, lead(b.StartOn,1,t.EndOn) over(order by b.StartOn) as Next
        , lag(b.EndOn,1,t.StartOn) over(order by b.StartOn) as Previous,Duration
    from @table t
    inner join @break b on b.EmployeeId = t.EmployeeId
    inner join counting c on c.EmployeeId=b.EmployeeId
), sorting as(
    select EmployeeId,TimeStart,TimeEnd,Duration,Number,Next,Previous,row_number() over(order by TimeStart) as [Row]
    from combine
), query as(
    select EmployeeId,
         TimeStart as StartOn, 
         TimeEnd as EndOn, 'A' as Type,Duration
    from sorting
    union all
    select EmployeeId,
         Previous,
         TimeStart, 'F' as Type,Duration
    from sorting
    union all 
    select EmployeeId,
         TimeEnd,
         [Next], 'F' as Type,Duration
    from sorting
    where [Row]=Number
)
select * from query order by StartOn

希望它能帮助其他开发者