-2

这是问题的延续/增加了复杂性: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

数据采用上述格式,但所需的输出和输入数据增加了复杂性。

需要考虑的要点是:

  1. 有两个入口代码:EN1,EN2 - 代表两个不同的办公室,但是两个办公室都使用相同的代码 EX 记录退出。在两个办公室花费的时间与员工的时间有关。

  2. 在某些情况下,员工可以尾随,因此可能会丢失与条目对应的退出记录(例如,考虑上面给定示例数据中的第 4 行和第 5 行),在这些情况下,我们必须突出显示退出缺失/无效的行VALIDITY 列的输出。

  3. 员工可以在第 1 天进入办公场所并在第 2 天退出(例如,考虑上面给出的示例数据中的第 8,9 行)对于这种情况,我们应该在输出中有 2 条记录/行:第 1 天的第一行:进入时间为 event_type:'EN1 or EN2' 的 swipe_time,退出时间:23:59 day2 的第二行:进入时间:00:00 ,退出时间为 event_type:'EX' 的 swipe_time

  4. 每条记录都应该有两个字段 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
4

1 回答 1

0

在朋友的帮助下,我解决了第 2 点中提到的问题:通过以下步骤,因为我只想要 sql 脚本中的解决方案,以我的一点 sql 知识,我分 3 步设计了解决方案,我相信它可以处理专家以更简单的方式:

将基表视为 EMP_DATA ,我使用了一个临时表: Temp_1 对于基表,我在最后一步添加了一个“VALIDITY”字段来标记记录。

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

第1步:

下面的查询将为 EMP_DATA 中的行分配行号并将它们复制到 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

第2步:

识别 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

第 3 步:

基于 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
于 2013-11-18T16:33:08.443 回答