过滤IN和OUT滑动在白天和夜班出勤转移?

时间:2013-07-04 17:51:14

标签: sql oracle plsql

我正在开发一个有白天和夜班的考勤系统。我无法过滤员工的IN和OUT拳?

对于班次时间:

  • 2013年6月29日,在22:00,OUT 07:00
  • 2013年6月30日,15:00,出口22:30

这是我目前的逻辑:

我根据换班时间和刷卡时间以及日期来过滤IN和OUT拳,但是当员工从夜班变为白班时,我遇到了问题。

以下是一个场景

该员工101岁,已于2013年6月29日晚上22:00打完夜班,第二天离开时间为2013年6月30日上午07:00。同一天,(2013年6月30日)他于2013年6月30日15:00来到办公室,并于同日22:30离开。

如果拳击每天都会出现,那么没有任何问题,但是由于任何问题都不会在2013年6月30日07:00 AM收到拳击,然后是在6月30日15:00 00:00 22:30 2013年已经在数据库中了2013年6月29日的出局是2013年6月30日上午7点很难找到这个作为前一天的冲击

注意:有时员工忘记刷入IN / OUT打卡

我该怎么做?

更新:

我们不知道哪种类型的冲头是IN或OUT,除非我需要与换班时间进行比较然后只有我可以决定它然而当员工从夜班变为白班然后最后一天夜班和白天的第一天IN和OUT出错了,因为29-Jun-13夜班他将在22:00来,他在30-jun-13 07:00离开,他再次来到办公室30 -jun-13在15:00和OUT是22:30现在为30-Jun-13我有三拳,这里拳可能会以不同的方式进入db在30-Jun-13将到来或者出场时间为29 -Jun-13将来或30-jun-13的OUT时间将到来,所以我在这里遇到问题

2 个答案:

答案 0 :(得分:0)

您需要的信息不仅仅是打卡时间。我建议你保持员工的当前状态('IN','OUT'或'ERROR')。然后,当收到打孔时,执行以下操作:

1.  If the employee status is ERROR:
    A. Record the punch as an ERROR which must be addressed by a supervisor.

2.  If the employee is IN:
    A. If the time since the last punch is greater than the max number of hours
       an employee is allowed to work consecutively
       i.  Flag the punch as an ERROR which must be addressed by a supervisor.
       ii. Change the status of the employee to ERROR.
    B. Otherwise:
       i. Treat this as an OUT punch.
       ii.  Change the status of the employee to OUT.

3.  If the employee is OUT:
    A. Treat this as an IN punch.
    B. Change the status of the employee to IN.

您需要提供一个主管时钟维护应用程序,以允许主管更新员工和拳头的状态,并根据需要删除或添加打孔。

答案 1 :(得分:0)

将您的表格考虑为:

emp_punch_time (empno, punch_time)

此表仅存储empno(即员工编号)和punch_time(包括日期和时间)。

在这种情况下,您可以执行以下操作:

WITH emp_punch_time AS (
-- This common table expression is just for your illustration.
-- When using this query on your base tables remove this CTE and make
-- appropriate changes to the subsequent queries.
SELECT 7369 AS empno
       , TO_DATE('29-JUN-2013 22:00:00', 'DD-MON-YYYY HH24:MI:SS') punch_time
  FROM dual
UNION
SELECT 7369, TO_DATE('30-JUN-2013 07:00:00', 'DD-MON-YYYY HH24:MI:SS') FROM dual
UNION
SELECT 7369, TO_DATE('30-JUN-2013 15:00:00', 'DD-MON-YYYY HH24:MI:SS') FROM dual
UNION
SELECT 7369, TO_DATE('30-JUN-2013 22:30:00', 'DD-MON-YYYY HH24:MI:SS') FROM dual
UNION
SELECT 7370, TO_DATE('29-JUN-2013 07:00:00', 'DD-MON-YYYY HH24:MI:SS') FROM dual
UNION
SELECT 7370, TO_DATE('29-JUN-2013 15:00:00', 'DD-MON-YYYY HH24:MI:SS') FROM dual
UNION
SELECT 7370, TO_DATE('29-JUN-2013 22:00:00', 'DD-MON-YYYY HH24:MI:SS') FROM dual
UNION
SELECT 7370, TO_DATE('30-JUN-2013 07:00:00', 'DD-MON-YYYY HH24:MI:SS') FROM dual
)
, punch AS (
SELECT p.empno
       , p.punch_time
       , CASE MOD(row_number() over (partition by empno
                                         order by p.punch_time asc), 2)
            WHEN 1 THEN 'IN'
            ELSE 'OUT'
         END AS punch_type
  FROM emp_punch_time p)
, punch_repo AS (
SELECT p.empno
       , p.punch_time AS in_time
       , (SELECT punch_time
            FROM punch p_out
           WHERE p_out.punch_type = 'OUT'
             AND p_out.empno = p.empno
             AND p_out.punch_time = (SELECT MIN(punch_time)
                                       FROM punch p_min
                                      WHERE p_min.punch_type = 'OUT'
                                        AND p_min.empno = p_out.empno
                                        AND p_min.punch_time > p.punch_time))
         AS out_time
  FROM punch p
 WHERE punch_type = 'IN'
)
SELECT empno
       , TO_CHAR(in_time, 'DD-MON-YYYY HH24:MI:SS') in_time
       , TO_CHAR(out_time, 'DD-MON-YYYY HH24:MI:SS') out_time
       , TRIM(TO_CHAR(FLOOR((out_time - in_time) * 24), '09'))
         ||':'
         || TRIM(TO_CHAR(FLOOR(MOD((out_time - in_time)*24, 1) * 60), '09'))
         AS time_spent
  FROM punch_repo
;

<强>输出

  EMPNO   IN_TIME                 OUT_TIME                TIME_SPENT
  7369    29-JUN-2013 22:00:00    30-JUN-2013 07:00:00    09:00
  7369    30-JUN-2013 15:00:00    30-JUN-2013 22:30:00    07:30
  7370    29-JUN-2013 07:00:00    29-JUN-2013 15:00:00    08:00
  7370    29-JUN-2013 22:00:00    30-JUN-2013 07:00:00    09:00