这是问题的继续/增加了复杂性:sql query - Get the difference time between swipe in - Swipe out for employee。我们有类似的刷入/输出数据,但有其他限制。
示例源数据:
EMPID EVENT_TYPE Swipe_time
1 EN1 2012-06-01 12:00
1 EX 2012-06-01 12:30
2 EN1 2012-06-01 12:50
1 EN2 2012-06-01 13:10
1 EN2 2012-06-01 15:50
2 EX 2012-06-01 13:30
2 EN1 2012-06-01 14:00
2 EX 2012-06-02 19:00
1 EX 2012-06-02 19:30
数据采用上述格式,但所需的输出和输入数据会增加复杂性。
要考虑的要点是:
有两个条目代码:EN1,EN2 - 代表两个不同的办事处,但两个办事处都记录退出时使用相同的代码EX。两个办公室的时间都与员工的时间有关。
在某些情况下,员工可以进行尾随,因此可能会丢失与条目相对应的退出记录(例如,考虑上面给出的样本数据中的第4行和第5行),在这种情况下我们必须强调该行说在输出的VALIDITY列下退出/无效。
员工可以在第1天进入办公室,并在第2天退出(例如,考虑上面给出的样本数据中的第8,9行),对于这种情况,我们应该在输出中有2个记录/行:第1行为第1天:进入时间为event_type的swipe_time:'EN1或EN2',退出时间:23:59第2行为第2天:进入时间:00:00,退出时间为event_type的swipe_time:'EX'
每条记录都应该有两个字段DAY_HOURS CALENDER_HOURS。如果员工在第1天的18:00进入并在第2天的3:00退出,DAY_HOURS = 8小时(完成工作时间)和CALENDER_HOURS = 6小时(特定日期的小时)
必需输出:表格格式如下:
EMPID EVENT_TYPE TIME_IN TIME_OUT DAY_HOURS CALENDER_HOURS VALIDITY
答案 0 :(得分:0)
在朋友的帮助下,我解决了 Point#2 中提到的问题:通过以下步骤,因为我只想在sql脚本中使用我的小sql知识,我设计了解决方案3个步骤,我相信专家可以更简单地处理它:
将基表视为EMP_DATA,我使用了一个临时表:Temp_1 对于基表,我添加了一个“有效性”字段来标记最后一步的记录。
<强> EMP_DATA:强>
EMPID EVENT_TYPE Swipe_time VALIDITY
1 EN1 2012-06-01 12:00
1 EX 2012-06-01 12:30
2 EN1 2012-06-01 12:50
1 EN2 2012-06-01 13:10
1 EN2 2012-06-01 15:50
2 EX 2012-06-01 13:30
2 EN1 2012-06-01 14:00
2 EX 2012-06-02 19:00
1 EX 2012-06-02 19:30
下面的查询将为EMP_DATA中的行分配rownumbers并将它们复制到temp_1表:
create table Temp_1 (EMP_ID int, Event_Type char(10), Swipe_Time datetime, rownum int, Lastevent char(10), Nextevent char(10))
Insert into Temp_1
SELECT EMP_ID, EVENT_TYPE,
ROW_NUMBER() OVER ( PARTITION BY EMP_ID
ORDER BY SWIPE_TIME ) AS RowNumber
FROM EMP_DATA
第1步输出:
EMPID EVENT_TYPE Swipe_time RowNumber LastEvent NextEvent
1 EN1 2012-06-01 12:00 1
1 EX 2012-06-01 12:30 2
2 EN1 2012-06-01 12:50 1
1 EN2 2012-06-01 13:10 3
1 EN2 2012-06-01 15:50 4
2 EX 2012-06-01 13:30 2
2 EN1 2012-06-01 14:00 3
2 EX 2012-06-02 19:00 4
1 EX 2012-06-02 19:30 5
识别temp_1表
行中每个事件的最后一个事件(上一个事件)和下一个事件 Update main set main.LastEvent =yy.LEvent,main.NextEvent=yy.NEvent
from TEMP_1 main
inner join
( SELECT A.EMP_ID , A.EVENT_TYPE, A.SWIPE_TIME, A.ROWNUMBER
COALESCE(LastVal.ZONE_NAME, 'N/A') AS LEvent ,
COALESCE(NextVal1.ZONE_NAME, 'N/A') AS NEvent
FROM Temp_1 A
LEFT JOIN Temp_1 LastVal
ON A.EMP_ID= LastVal.EMP_ID
AND A.ROWNUMBER - 1 = LastVal.ROWNUMBER
LEFT JOIN Temp_1 NextVal1
ON A.EMP_ID= NextVal1.EMP_ID
AND A.ROWNUMBER + 1 = NextVal1.ROWNUMBER)yy
on main.EMP_ID=yy.EMP_ID,
and main.event_type=yy.event_type
and main.swipe_time = yy.swipe_event
第2步输出:
EMPID EVENT_TYPE Swipe_time RowNumber LastEvent NextEvent
1 EN1 2012-06-01 12:00 1 N/A EX
1 EX 2012-06-01 12:30 2 EN1 EN2
2 EN1 2012-06-01 12:50 1 N/A EX
1 EN2 2012-06-01 13:10 3 EX EN2
1 EN2 2012-06-01 15:50 4 EN2 EX
2 EX 2012-06-01 13:30 2 EN1 EN1
2 EN1 2012-06-01 14:00 3 EX EX
2 EX 2012-06-02 19:00 4 EN1 N/A
1 EX 2012-06-02 19:30 5 EN2 N/A
基于LastEvent和NextEvent,我们可以识别尾随的条目,并通过以下查询更新主表EMP_DATA:
Update emp set emp.VALIDITY='N'
from EMP_DATA
INNER JOIN
(select *
from TEMP_1
where (EVENT_TYPE = 'EX' and LastEvent = 'EX')
or (EVENT_TYPE IN ('EN1','EN2') and NextEvent IN ('EN1','EN2')))yy
ON emp.EMP_ID = yy.EMP_ID
and emp.EVENT_TYPE = yy.EMP_ID
and emp.Swipe_time = yy.Swipe_time
最终输出: * 第3步输出: *
EMPID EVENT_TYPE Swipe_time VALIDITY
1 EN1 2012-06-01 12:00
1 EX 2012-06-01 12:30
2 EN1 2012-06-01 12:50
1 EN2 2012-06-01 13:10 N
1 EN2 2012-06-01 15:50
2 EX 2012-06-01 13:30
2 EN1 2012-06-01 14:00
2 EX 2012-06-02 19:00
1 EX 2012-06-02 19:30