Punch-IN和Punch-OUT

时间:2016-08-30 11:55:53

标签: sql-server datetime sql-server-2012

我正在尝试在SQL Server 2012中为报告创建一个SQL查询,并提出了以下查询。此查询使用临时表(EmpName, EntryDate, EntryTime, TrnName, TrnCode)中的数据。

数据不一致并操纵它。下面的代码使用了level2中提到的多个场景,但我想编辑下面的查询,在最终时间计算之前为任何缺失的打孔(入口或出口)放置NULL值。

以下是样本数据。

EmpName    EventDate    EventTime           TrnName    TrnCode
A         2015-07-20    11:07:29.0000000    Entrance    0
A         2015-07-20    11:08:09.0000000    Exit        1
A         2015-07-20    21:13:27.0000000    Exit        1
A         2015-07-21    12:07:03.0000000    Entrance    0
A         2015-07-21    21:04:02.0000000    Exit        1
A         2015-07-22    11:48:06.0000000    Entrance    0
A         2015-07-22    13:57:58.0000000    Entrance    0
A         2015-07-22    13:37:15.0000000    Exit        1
A         2015-07-22    20:59:22.0000000    Exit        1
B         2016-06-20    23:03:33.0000000    Entrance    0
B         2016-06-21    02:36:38.0000000    Exit        1
B         2016-06-21    17:02:29.0000000    Entrance    0
B         2016-06-21    17:27:03.0000000    Entrance    0
B         2016-06-21    19:11:24.0000000    Exit        1
B         2016-06-21    19:24:41.0000000    Entrance    0
B         2016-06-21    23:35:25.0000000    Exit        1
B         2016-06-21    23:57:03.0000000    Entrance    0
B         2016-06-22    17:27:00.0000000    Exit        1
B         2016-06-22    17:42:01.0000000    Entrance    0
B         2016-06-22    19:37:43.0000000    Exit        1
B         2016-06-22    21:27:35.0000000    Entrance    0
B         2016-06-22    21:27:59.0000000    Exit        1
B         2016-06-22    21:45:47.0000000    Exit        1
B         2016-06-22    21:56:15.0000000    Entrance    0
B         2016-06-23    00:42:44.0000000    Exit        1
B         2016-06-23    01:03:06.0000000    Entrance    0
B         2016-06-23    02:47:18.0000000    Exit        1

我没有为每位员工设置任何固定班次时间,并且想要检查每次打卡之间的时差是否大于阈值(14小时),然后将OUT视为错误打卡或者通常计算小时差异。

;WITH Level1 
 AS ( 
 SELECT 
 EmpName (or EmpID) 
,TrnName (Exit or Entrance)
,CAST(EventDate AS DATETIME) + CAST(EventTime AS DATETIME) AS EntryDateTime
,LAG (TrnName, 1, 'N/A') OVER ( PARTITION BY EmpName ORDER BY EntryDateTime) AS LastEvent
,LEAD(TrnName, 1, 'N/A') OVER ( PARTITION BY EmpName ORDER BY EventDateTime ) AS NextEvent 
 FROM #TempData 
),
Level2
AS ( 
 SELECT 
 EmpName 
,TrnName 
,EntryDateTime 
,LastEvent
,NextEvent 
FROM   Level1 
WHERE
    NOT ( TrnName = 'Entrance' AND NextEvent = 'Entrance' )
    AND NOT ( TrnName = 'Entrance' AND LastEvent = 'Entrance' )
    AND NOT ( TrnName = 'Exit' AND LastEvent = 'Exit' )
    AND NOT ( TrnName = 'Entrance' AND NextEvent = 'N/A' ) 
    AND NOT (TrnName = 'Exit' AND LastEvent = 'N/A' )
),
Level3
AS ( 
 SELECT 
 EmpName
,TrnName 
,EntryDateTime 
,DATEDIFF(second, EntryDateTime,LEAD(EntryDateTime) OVER ( PARTITION BY EmpName ORDER BY EntryDateTime )) AS Seconds 
FROM Level2 
)

 SELECT 
 EmpName 
,EntryDateTime 
,(EntryDateTime+convert(DateTime,TIMEFROMPARTS((Seconds%(3600*24)/3600), ((Seconds%(3600*24)%3600)/60), ((Seconds%(3600*24)%3600)%60),0, 0))) AS ExitDateTime
,Seconds
,TIMEFROMPARTS((Seconds%(3600*24)/3600), ((Seconds%(3600*24)%3600)/60), ((Seconds%(3600*24)%3600)%60),0, 0) AS WorkTime
FROM Level3 
WHERE TrnName = 'Entrance'

预期结果:

Empname | EntryDateTime | ExitDateTime | Difference(Seconds) | Difference(hh:mm:ss)
A | 2015-07-20 11:07:29.000 | 2015-07-20 11:08:09.000 | 40   | 00:00:40
A | NULL                    | 2015-07-20 21:13:27.000 | NULL | NULL
A | 2015-07-21 12:07:03.000 | 2015-07-21 21:04:02.000 | 32219| 08:56:59
B | 2016-01-11 16:25:35.000 | 2016-01-11 17:59:42.000 | 5647 | 01:34:07
B | 2016-01-11 18:11:55.000 | 2016-01-11 20:18:48.000 | 7613 | 02:06:53
B | 2016-01-11 23:06:06.000 |                    NULL | NULL | NULL
B | 2016-01-12 00:29:17.000 |                    NULL | NULL | NULL
B | 2016-01-12 01:32:55.000 | 2016-01-12 01:39:54.000 | 419  | 00:06:59
B | 2016-06-21 23:57:03.000 | 2016-06-22 17:27:00.000 |62997 | 17:29:57 

- 最后一条记录不正确,因为21-6-16的最后一次输入时间为输入,而外出时间为22-06-16的第一次输出。在这种情况下,OUT-Time值应为NULL,并且在下一条记录中,IN-Time值应为NULL,OUT时间为2016-06-22 17:27:00.000

0 个答案:

没有答案