确定MySQL中预定义班次内的时间范围

确定MySQL中预定义班次内的时间范围,mysql,time,Mysql,Time,我正在使用一个考勤卡数据库,试图确定每一次打卡需要多少时间在三个不同的轮班周期中 For example shift 1 = 7AM - 3pm shift 2 = 3pm - 11pm shift 3 = 11pm - 7am Joe clocks in at 6:45AM and out at 1:45PM 15分钟的时间需要计算为3班的时间,但我不确定如何在MySQL中分割出这段时间。我所拥有的只是一个时间输入和时间输出字段 有三个轮班周期: Shift TimeStart Ti

我正在使用一个考勤卡数据库,试图确定每一次打卡需要多少时间在三个不同的轮班周期中

For example
shift 1 = 7AM - 3pm
shift 2 = 3pm - 11pm
shift 3 = 11pm - 7am

Joe clocks in at 6:45AM and out at 1:45PM
15分钟的时间需要计算为3班的时间,但我不确定如何在MySQL中分割出这段时间。我所拥有的只是一个时间输入和时间输出字段

有三个轮班周期:

Shift  TimeStart   TimeEnd
1      07:00       15:00
2      15:00       23:00
3      23:00       07:00
样本数据

ID    TimeIn            TimeOut           Hours
100   2014-07-31 06:45  2014-07-31 13:45  7
期望的结果

ID    Shift  TimeWorked
100   1      06:45
100   2      00:00
100   3      00:15

我能够使用PHP找到解决方案

我所做的是逐分钟循环每一次打孔,并确定每一分钟的时间跨度适用于什么样的移位。在循环中,我为班次1、2、3或0(无班次工资)增加4个变量中的一个,最后,将这些变量转储到数据库中,以用于分析的记录

$query = "SELECT * FROM source_filtered_timecard";
$result_set = mysqli_query($connection, $query);

while($record = mysqli_fetch_assoc($result_set)) {
    $checkCount++;
    $shift1_hours = 0; $shift2_hours = 0;
    $shift3_hours = 0; $shift0_hours = 0;

    $time = strtotime($record['in_time']); 
    $time_out = strtotime('-1 Minute',strtotime($record['out_time']));

    while($time <= $time_out) {
        $mysql_time = date('G:i:s',$time);

        //SELECT SHIFT CODE THAT APPLIES TO CURRENT PIT//
        $query = "SELECT shift FROM shift_rules WHERE STR_TO_DATE('{$mysql_time}','%H:%i:%S') BETWEEN start_time_24 AND end_time_24 LIMIT 1";
        $current_shift_set = mysqli_query($connection, $query);

        if(mysqli_num_rows($current_shift_set) == 1) {
            $current_shift = mysqli_fetch_assoc($current_shift_set);
            if($current_shift['shift'] == '1'){$shift1_hours++;}
            elseif($current_shift['shift'] == '2'){$shift2_hours++;}
            elseif($current_shift['shift'] == '3'){$shift3_hours++;}
            else{$shift0_hours++;}
        } else {
            $shift0_hours++;
        }
        //INCRIMENT TIME BY 1 MINUTE//
        $time = strtotime("+1 minute",$time);
    }

    $shift1_hours = $shift1_hours/60;
    $shift2_hours = $shift2_hours/60;
    $shift3_hours = $shift3_hours/60;
    $shift0_hours = $shift0_hours/60;

    //UPDATE TIMECARD ROWS WITH SHIFT HOURS//
    $query = "UPDATE source_filtered_timecard 
              SET shift1_time = {$shift1_hours}, 
                  shift2_time = {$shift2_hours},
                  shift3_time = {$shift3_hours},
                  shift0_time = {$shift0_hours}
              WHERE id = '{$record['id']}'";
    $update = mysqli_query($connection, $query);
}
$query=“选择*源\过滤\时间卡”;
$result\u set=mysqli\u query($connection,$query);
而($record=mysqli\u fetch\u assoc($result\u set)){
$checkCount++;
$shift1\u小时=0;$shift2\u小时=0;
$shift3_小时=0;$shift0_小时=0;
$time=strottime($record['in_time']);
$time_out=strottime('-1分钟),strottime($record['out_time']);

虽然($time我会用PHP来做这件事。看看Joe的例子,一开始很想弄清楚他的数据是如何映射到移位规则上的。但是,我认为如果换一种方法,也就是将规则映射到他的数据上,直到没有数据可分类,这将是一个更简洁的解决方案

算法可能有点像这样:

  • 乔的剩余时间是6:45-13:45
让我们将第一条规则映射到它(即,该规则对该范围的贡献有多大?):

  • 班次1=7:00-15:00(6:45小时)
现在乔的剩余时间是:

  • 6:45-7:00
执行下一个规则:

  • 班次2=15:00-23:00(0小时)
因此,乔的剩余时间不变。最后一条规则是:

  • 班次3=23:00-1d7:00(0:15小时)
有几件事需要注意:

  • 工作时间量可以存储在一个数组中(“工作时间集”)。它从一个简单的开始和结束开始,但如果规则从中间删除一段时间,它可能会分为两个开始和两个结束
  • 应用规则时,将其转换为实际时间戳(即日期和时间),以便正确包装到第二天
  • 编写一个函数,该函数接受工作时间集,加上规则开始和结束时间戳,修改工作时间集,并返回规则的小时数

首先,您需要添加day列以区分23:59:59到次日的时间

id |班次|姓名|时间|开始|时间|结束|日期 1 |白班|“07:00:00”|“18:59:59”| 1 2 |夜班|“19:00:00”|“06:59:59”| 2

程序:


分隔符$$CREATE PROCEDURE sp_check_shift(在intime时间内)PROC:begin IF(intime>='00:00:01'和intimeShow确切显示(表结构)时间存储方式。编辑以包含结构我不太清楚您想要什么,但我认为您需要:UNIX_时间戳,从_UNIXTIME_到_SEC(),SEC_到_time()@KirkLogan我不认为我完全理解你的要求。介意用一些样本数据和你想要的结果更新你的问题吗?@KirkLogan我编辑了你的问题。如果有任何信息不正确,请告诉我。