2013-10-03 123 views
0

我目前正在进行工资发放。我已经设法在同一天计算出入职和退休员工的小时数。以下是我正在提取的记录的样本表。我的问题是,如果员工在晚上10点到早上6点的班次或类似的班次工作,要求他们在第二天工作,我无法弄清楚使用什么条件。 Im在我的查询中使用distinct,因为hr提供的数据包含许多重复条目。从特定日期获得记录

---------------------------------------------------- 
| empID  | Date  | Type | RecTime | 
---------------------------------------------------- 
| 1  | 2012-11-01 | 1-TIME IN | 21:45 | 
| 1  | 2012-11-02 | 1-TIME OUT | 06:05 | 
| 1  | 2012-11-02 | 1-TIME IN | 21:33 | 
| 1  | 2012-11-03 | 1-TIME OUT | 06:08 | 
| 1  | 2012-11-04 | 1-TIME IN | 11:49 | 
| 1  | 2012-11-04 | 1-TIME OUT | 21:39 | 
| 1  | 2012-11-05 | 1-TIME IN | 14:25 | 
| 1  | 2012-11-05 | 1-TIME OUT | 20:07 | 
---------------------------------------------------- 

这是我的PHP代码:

<?php 

$c = 1; 
$query = mysql_query("SELECT DISTINCT EmpID, Date, Type from paymaster2c.tx_tito_pm ORDER BY EmpID, Date"); 
while ($row = mysql_fetch_array($query)){ 
$EID = $row['EmpID']; 
$D = $row['Date']; 
$T = $row['Type']; 

$RTi = 'no time in'; 
$RTo = 'no time out'; 
$RBo = 'no break out'; 
$RBi = 'no break in'; 

$query1 = mysql_query("SELECT RecTime from tx_tito_pm WHERE Date='$D' AND EmpID='$EID' AND Type='1-TIME IN' LIMIT 1"); 
while ($row1 = mysql_fetch_array($query1)){ 
$RTi = date('H:i:s',strtotime($row1['RecTime'])); 

    if (date('H:i:s',strtotime('$RTi')) > date('H:i:s',strtotime('03:00 PM')) && date('H:i:s',strtotime('$RTi')) <= date('H:i:s',strtotime('11:59 PM'))) { 
    $date = new DateTime('$D'); 
     $date->add(new DateInterval('P1D')); 
     $NewDate = $date->format('Y-m-d'); 

     //$NewD = date('Y-m-d', strtotime('$D + 1day')); 
     $query3 = mysql_query("SELECT RecTime from tx_tito_pm WHERE Date='$date' AND EmpID='$EID' AND Type='4-TIME OUT' LIMIT 1"); 
      while ($row3 = mysql_fetch_array($query3)){ 
       $RTo = date('H:i:s',strtotime($row3['RecTime'])); 

       $RTii = date('H:i:s',strtotime('23:59:00')) - date('H:i:s',strtotime($RTi)); 

      $start_date = new DateTime(date('H:i:s',strtotime('23:59:00'))); 
      $since_start = $start_date->diff(new DateTime(date('H:i:s',strtotime('$RTi')))); 
      $start_date1 = new DateTime(date('H:i:s',strtotime('00:00:00'))); 
      $since_start1 = $start_date1->diff(new DateTime(date('H:i:s',strtotime('$RTo')))); 

      $M1 = $since_start1->i ; 
      $H1 = $since_start1->h ; 
      $M = $since_start->i ; 
      $H = $since_start->h ; 
      $a = $H + $H1; 
      $b = $M + $M1; 


      $RTD = $RTo-$RTi; 

      echo "#" .$c. " ". $EID . " == " . $D . " == " . date('D', strtotime($D)) ." == " . $T ." ==>>" .$RTo. "-". $RTi. "==" .$RTD. "//" .$a. "hrs and " .$b. "minutes. <br /> \n"; 
      $c++; 
      } 

    } 
    else { 

    $query2 = mysql_query("SELECT RecTime from tx_tito_pm WHERE Date='$D' AND EmpID='$EID' AND Type='4-TIME OUT' LIMIT 1"); 
     while ($row2 = mysql_fetch_array($query2)){ 
     $RTo = date('H:i:s',strtotime($row2['RecTime'])); 

      $start_date = new DateTime(date('H:i:s',strtotime($RTo))); 
      $since_start = $start_date->diff(new DateTime(date('H:i:s',strtotime($RTi)))); 

      $M = $since_start->i ; 
      $H = $since_start->h ; 


      $RTD = $RTo-$RTi; 

      echo "#" .$c. " ". $EID . " == " . $D . " == " . date('D', strtotime($D)) ." == " . $T ." ==>>" .$RTo. "-". $RTi. "==" .$RTD. "//" .$H. "hrs and " .$M. "minutes. <br /> \n"; 
      $c++; 

     } 
    } 
} 


} 
echo $c; 
?> 

希望有人能帮助我。非常感谢你提前。

+0

请不要使用'mysql_ *',它已经过时并且不安全。阅读关于PDO和MySQLi。 –

+0

您需要维护表级别的额外信息。需要保持每个员工工作的转变,每个班次的开始和结束时间。您不应该使用DISTINCT,因为员工可能会在班次中多次进入和退出。有了这些信息,你应该能够满足要求。 – rags

+1

@FranciscoPresencia,我现在还在尝试学习PDO和MySQLi。仍然在学习,但是,尽管如此。:) – user2842120

回答

0

我认为你需要最终开发新的或额外的表来帮助你解决这个问题(如果你想追求一个以MySQL为中心的解决方案)。下面是一个强力的查询,可能需要优化/个性化,包括:

  • 确保您有所需的字段的索引
  • (恕我直言)创建SQL视图来封装这些派生表(即在括号内重复选择)
  • 我不知道你的字段类型。所以我认为时间是一个字符场。这可能需要更改
  • 您可能希望运行此查询的变体来填充临时表或工作表。随着数据集的增长,确定轮班结束的自加入将变得密集
  • 最后,当数据具有不匹配/配对的值时(例如,没有结帐的两个签入 - 反之亦然) 。)

对于演示看到:http://sqlfiddle.com/#!2/558fb/22

样本输出

| EMPID |       CHECKIN |      CHECKOUT | WORKED | 
|-------|---------------------------------|---------------------------------|--------| 
|  1 | November, 01 2012 21:45:00+0000 | November, 02 2012 06:05:00+0000 | 8.3333 | 
|  1 | November, 02 2012 21:33:00+0000 | November, 03 2012 06:08:00+0000 | 8.5833 | 
|  1 | November, 04 2012 11:49:00+0000 | November, 04 2012 21:39:00+0000 | 9.8333 | 
|  1 | November, 05 2012 14:25:00+0000 | November, 05 2012 20:07:00+0000 | 5.7 | 

SQL代码:

SELECT TimeIn.empID, TimeIn.BetterDate AS CheckIn, TimeOut.BetterDate AS CheckOut 
, (TO_SECONDS(TimeOut.BetterDate) - TO_SECONDS(TimeIn.BetterDate))/(60*60) AS Worked 
FROM (
SELECT empID, Type, Date, RecTime, DATE_ADD(Date, Interval RecTime HOUR_MINUTE) as BetterDate 
FROM timedata) AS TimeIn 
LEFT JOIN (
    SELECT empID, Type, Date, RecTime, DATE_ADD(Date, Interval RecTime HOUR_MINUTE) as BetterDate 
    FROM timedata) AS TimeOut 
ON TimeIn.EmpID = TimeOut.EmpID 
    AND TimeIn.BetterDate < TimeOut.BetterDate 
    AND TimeOut.Type = '1-TIME OUT' 
    AND NOT EXISTS 
    (SELECT * 
    FROM TimeData 
    WHERE TimeData.Type = '1-TIME OUT' 
     AND DATE_ADD(Date, Interval RecTime HOUR_MINUTE) < TimeOut.BetterDate 
     AND DATE_ADD(Date, Interval RecTime HOUR_MINUTE) > TimeIn.BetterDate) 
WHERE TimeIn.Type = '1-TIME IN' 
ORDER BY CheckIn, CheckOut