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

时间:2014-08-01 20:41:28

标签: 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   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

SQL Fiddle

3 个答案:

答案 0 :(得分:2)

我能够使用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);
}

答案 1 :(得分:0)

我在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小时)

有几点需要注意:

  • 工作时间可以存储在一个数组中(&#34;工作时间设置&#34;)。它从一个简单的开始和结束开始,但如果规则从中间移除了一大块时间,它可能分为两个开始和两个结束
  • 应用规则时,将它们转换为实际时间戳(即日期和时间),以便第二天的包装正常工作
  • 编写一个需要工作时间设置的函数,加上规则开始和结束时间戳,修改工作时间集,并返回规则的小时数

答案 2 :(得分:-1)

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

ID | shift_name | time_start | time_end |天 1 |日班| '07:00:00'| '18:59:59'| 1 2 |夜班| '19:00:00'| '06:59:59'| 2

程序:

DELIMITER $$ CREATE PROCEDURE sp_check_shift(IN intime time)PROC:开始IF(intime&gt; ='00:00:01'和intime&lt; ='23:59:59')那么(SELECT 1 FROM tbl_shift WHERE time_start&lt ; = intime AND time_end&gt; = intime AND day = 1)那么SELECT shift_name FROM tbl_shift WHERE time_start&lt; = intime AND time_end&gt; = intime AND day = 1; ELSEIF(SELECT 1 FROM tbl_shift WHERE time_start&lt; = intime AND day = 2)THEN SELECT shift_name FROM tbl_shift WHERE time_start&lt; = intime AND day = 2; ELSEIF(SELECT 1 FROM tbl_shift WHERE time_end&gt; = intime AND day = 2)THEN SELECT shift_name FROM tbl_shift WHERE time_end&gt; = intime AND day = 2; END IF; ELSE SELECT '无效时间'shift_name; END IF; END $$分隔符;