检查其他时间范围内的时间范围

时间:2017-03-16 08:15:36

标签: sql sql-server database

我有一个Time In和Time Out,并且有午餐早餐和晚餐定义的时间范围。我想要的是从出勤时间(Time In And Time Out)中减去这些时间。

样本数据是

出勤表数据

EMPID 1095

TimeIN  2017-03-01 08:52:45.000

TimeOut 2017-03-01 19:59:18.000

The Mess Timings

type    StartTime   EndTime
BreakFast   06:30:39    10:00:39
Dinner  19:00:39    21:00:39
Lunch   12:00:23    15:00:23

我需要的是从实际出勤时间中减去这些混乱时间,以获得实际的员工值班时间。

感谢。

3 个答案:

答案 0 :(得分:0)

此方法使用数字表创建一个查找表,其中包含@TimeIn@TimeOut值之间的所有秒数。这将适用于多天的时期,尽管有一些严重的警告:

  • 早餐,午餐和晚餐每天都在同一时间。
  • 您的@TimeIn@TimeOut期间没有那么大,它会溢出包含int数量的seconds值。
    • 在这种情况下,您需要使用minutes或找到不同的方法
  • 您的返回值少于24小时。
    • 在这种情况下,只是不要将差异作为time数据类型返回并相应地处理。
declare @TimeIn datetime    = '2017-03-01 08:52:45.000'
        ,@TimeOut datetime  = '2017-03-01 19:59:18.000'

        ,@BStart time       = '06:30:39'
        ,@BEnd time         = '10:00:39'
        ,@LStart time       = '12:00:23'
        ,@LEnd time         = '15:00:23'
        ,@DStart time       = '19:00:39'
        ,@DEnd time         = '21:00:39';

-- Create numbers table then use it to build a table os seconds between TimeIn and TimeOut
with n(n) as (select n from (values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) as n(n))
    ,s(s) as (select top (select datediff(s,@TimeIn,@TimeOut)+1) dateadd(s,row_number() over (order by (select 1))-1,@TimeIn) from n n1,n n2,n n3,n n4,n n5,n n6)
select cast(dateadd(s,count(1),0) as time) as s
from s
where s between @TimeIn and @TimeOut    -- Return all seconds that aren't within Breakfast, Lunch or Dinner
    and cast(s as time) not between @BStart and @BEnd
    and cast(s as time) not between @LStart and @LEnd
    and cast(s as time) not between @DStart and @DEnd

返回:05:59:58.0000000

答案 1 :(得分:0)

我在其他桌子上每天都有乱七八糟的时间,所以我创建了一个视图并在每日出勤前占据了所有字段,然后使用案例陈述将时间与每日出勤时间相匹配。

EmployeeID  AttendanceDate  ShiftID TimeIn  TimeOut BreakOut    BreakIn LeaveType   TotalHours  LeaveHours  ATOThours   DeductedHrs OTHours UserID  AudtDate    Reason  SM  SY  OTDed   DutyDed Mark    Expr1   MARKL   BreakFastStart  BreakFastEnd    LunchStart  LunchEnd    DinnerStart DinnerEnd
1095    2017-03-01 00:00:00.000 1   2017-03-01 08:52:45.000 2017-03-01 19:59:18.000 NULL    NULL    NULL    0   NULL    0   0   0   NULL    NULL    NULL    3   2017    NULL    NULL    NULL    NULL    NULL    2017-02-20 06:30:34.000 2017-02-20 09:30:34.000 2017-02-20 12:00:26.000 2017-02-20 15:00:26.000 2017-02-20 19:00:59.000 2017-02-20 21:00:59.000

现在,随着时间的推移,检查它的可信度会很好。

感谢您的支持

答案 2 :(得分:0)

您还可以在表的View OR in JOIN查询中使用以下脚本。注意我得到了一个不同的答案,我认为是正确的。

SELECT CONVERT(varchar, DATEADD(ss, 
        (DATEDIFF(ss,TimeIn, [TimeOut]) -
         (
            DATEDIFF(ss,[BreakFastStartTime], [BreakFastEndTime]) + 
            DATEDIFF(ss,[LunchStartTime], [LunchEndTime]) +
            DATEDIFF(ss,[DinnerStartTime], [DinnerEndTime]) 
         )
        ), 0), 108) 
FROM [Attendance Data] 

对于您的示例,答案为02:36:33