2017-03-16 130 views
1

我有一个时间和超时,并且有一个时间范围为午餐早餐和晚餐定义。我想要的是从出席时间(时间和时间)中减去这些时间。检查其他时间范围的时间范围失效

的样品数据

考勤表数据

EMPID 1095 

TimeIN 2017-03-01 08:52:45.000 

TimeOut 2017-03-01 19:59:18.000 

混乱时序

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

我需要的是从实际出勤时间减去这些乱七八糟的时机,以获得实际员工值勤时间。

感谢。

+0

嗨,你可以有多个时间在和超时一天?或者它是固定的1次,每天1次出去 –

+0

甚至更​​难 - 时间在一天,并在下一个时间(如在夜班)? –

+0

那么我已经整理出来的时间进出是单次进入。 – Kamran

回答

0

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

  • 早餐,午餐和晚餐是在同一时间每天。
  • 您的@TimeIn@TimeOut期间没有那么大,它溢出了包含seconds的数字的int值。
    • 在这种情况下,你将需要或者只是使用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

0

我已经在其他表乱七八糟的日常定时,我创建了一个视图,把各个领域的日常考勤面前,然后使用case语句将时间与每日考勤时间相匹配。

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 

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

感谢支持

0

您也可以使用下面的脚本在视图或连接表的查询。注意我得到了一个我认为是正确的不同答案。

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