我目前正在做工资单。我已经设法在同一天计算出有时间和超时的员工小时数。这是我正在获取的记录的示例表。我的问题是,如果员工在晚上10点到6点班次或类似班次工作,要求他们工作到第二天,我无法弄清楚应该使用什么条件。我在查询中使用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 :(得分:0)
我认为你需要最终开发新的或额外的表来帮助解决这个问题(如果你想要追求以MySQL为中心的解决方案)。以下是可能需要优化/个性化的强力查询,包括:
对于演示,请参阅: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