我正在进行基于班次的应用,我的工作人员分三班,早上6点到下午2点,下午2点到晚上10点,晚上10点到早上6点(第二天)工作。 我需要计算在数据库中记录的每个班次的总工作时间。
$clientid = $_GET["clientid"];
$date = $_GET["edate"];
$shift = $_GET["shift"];
if(!empty($clientid))
{
if($shift=='a')
{
$sq = mysql_query("SELECT * from logusage WHERE etime BETWEEN '6:00:00' AND '14:00:00' AND clientid= '$clientid' AND edate = '$date'",$this->db);
}
else if($shift=='b')
{
$sq = mysql_query("SELECT * from logusage WHERE etime BETWEEN '14:00:00' AND '22:00:00' AND clientid= '$clientid' AND edate = '$date'",$this->db);
}
else if($shift=='c')
{
$sq = mysql_query("SELECT * from logusage WHERE etime BETWEEN '22:00:00' AND '6:00:00' AND clientid= '$clientid' AND edate= '$date'",$this->db);
}
每当我尝试访问Shift C时,它只会在当天晚上11:59之前提取数据,因为我也在解析日期。如何更改sql以获取第二天的数据,直到早上6点?
答案 0 :(得分:1)
对于第三个,您需要减去小时以获得正确的日期:
SELECT *
FROM logusage
WHERE etime BETWEEN '22:00:00' AND '6:00:00' AND
clientid= '$clientid' AND
date(date_sub(edate, interval 6 hour)) = '$date';
答案 1 :(得分:1)
我强烈建议您将EDATE和ETIME作为TIMESTAMP值存储在单个列中,而不是2个单独的列。将时间戳存储为GMT + 00值而不是当地时间也是一种很好的做法 - 但这仅在您当地时间使用DST(白天节省灯)时才有意义。请尝试以下代码:
$clientid = (int)$_GET["clientid"];
$date = $_GET["edate"];
$shift = $_GET["shift"];
if($clientid != 0 AND $date != '')
{
// I suppose $date is in format YYYY-MM-DD
list($year,$month,$day) = preg_split('/-/',$date);
switch($shift)
{
case 'a':
$beg_stamp = mktime(6,0,0,$month,$day,$year);
$end_stamp = $beg_stamp + 8*3600 - 1;
break;
case 'b':
$beg_stamp = mktime(14,0,0,$month,$day,$year);
$end_stamp = $beg_stamp + 8*3600 - 1;
break;
case 'c':
$beg_stamp = mktime(22,0,0,$month,$day,$year);
$end_stamp = $beg_stamp + 8*3600 - 1;
break;
}
if($beg_stamp != '' AND $end_stamp != '') // not strictly needed, if $shift is always valid
$sq = mysql_query('SELECT * from logusage WHERE clientid = '.$clientid.' AND TIMESTAMP(edate,etime) BETWEEN "'.date('Y-m-d H:i:s',$beg_stamp).'" AND "'.date('Y-m-d H:i:s',$end_stamp).'" ORDER BY edate,etime',$this->db);
}
你从$ end_stamp中减去1,因为SQL谓词BETWEEN是包容性的 - 即 x BETWEEN y AND z 等同于 x> = y AND x< = z 强>你不想抓住属于下一班的工作。