简体   繁体   中英

Fetch data by time shifts - PHP MYSQL

I am working on a shift based application where my workers work in 3 shifts, Morning 6am to 2pm, 2pm to 10pm and 10pm to 6am(next day). I need to calculate to total time worked in each shifts which is logged in the database.

  $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);
    }

Whenever I try to access the Shift C, it fetches me data only till 11:59PM on that day as I am parsing the date too. How do I alter the sql to fetch data for the next day, till 6AM too?

For the third one, you need to subtract hours to get the date correct:

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';

I strongly suggest you to store EDATE and ETIME in a single column as TIMESTAMP value instead of 2 separate columns. It is also a good practice to store timestamps as GMT+00 values instead of your local time - but this only matters if your local time uses DST (day-light saving). Try the following code:

$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);
}

You subtract 1 from the $end_stamp because the SQL predicate BETWEEN is inclusive - ie x BETWEEN y AND z is equivalent to x >= y AND x <= z and you do not want to catch work which belongs to the next shift.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM