用于获取日期表中可用时间范围的算法或SQL

时间:2013-12-30 13:55:23

标签: php mysql sql

我有一个问题,一个好的,有效的方法,从日期表中得到不存在日期。

我有下面的日期表。用户将选择一个时间范围来“预订”可用的地点(不完全是预订申请,但它接近于此)。

我想我会检查用户选择的范围是否与表格中的日期重叠。如果列在startRange和endRange之间,我会做一些select count。这不是我的主要问题......如果没有重叠,我会插入新的时间范围。

我的问题是如何在用户选择的相同持续时间内获得最近的时间范围。

例如,用户选择startDate = 2013-12-30 11:00:00和endDate = 2013-12-30 12:00:00。

id  startRange          endRange            tstStart   tstEnd
1   2013-12-30 11:00:00 2013-12-30 12:00:00 1388394000  1388397600
2   2013-12-30 14:00:00 2013-12-30 15:00:00 1388408400  1388412000
3   2013-12-30 16:00:00 2013-12-30 17:00:00 1388408400  1388412000
4   2013-12-30 18:00:00 2013-12-30 19:00:00 1388422800  1388426400
5   2013-12-30 22:00:00 2013-12-30 23:00:00 1388437200  1388440800

所需的输出将是这样的(我们只显示四个最近的可用时间范围):

From 2013-12-30 12:00:00 to 2013-12-30 13:00:00
From 2013-12-30 13:00:00 to 2013-12-30 14:00:00
From 2013-12-30 15:00:00 to 2013-12-30 16:00:00
From 2013-12-30 17:00:00 to 2013-12-30 18:00:00

感谢Kielni,我对如何解决这个问题有了一个小小的想法。此代码获得与用户选择的时间范围最接近的时间范围。

这是一些php:

public function selectCercanos(){
    $rangeStart = 1388394000;
    $rangeEnd = 1388397600;
    $dif = $rangeEnd - $rangeStart;

    $sql = 'select p.startRange, p.endRange, p.tstIni, p.tstEnd from TimeRanges p
        order by abs(p.tstIni-:rangeStart) asc limit 4;';
    $params = array (
            ':rangeStart' => $rangeStart
        );

    return $this->find ( $sql, $params ); //PDO method
}

这样我就知道了有序时间范围之间的间隙持续时间

public function getFechasCercanas(){
    $tiemposCercanos = $this->selectCercanos();
    $res = $this->selectCercanos();
    $tmp = null;
    foreach($res as $row){
        if($tmp == null){
            $tmp = $row;
            continue;
        }
        $dt1 = new DateTime($tmp['endRange']);
        $dt2 = new DateTime($row['startRange']);
        $interval = $dt1->diff($dt2);
         $interval->format('%H horas')."\n";
        echo "from: ".$tmp['endRange']. " to: ".$row['startRange']. " lapse: ".
             $interval->format('%y years %m months %d days %H hours')."\n";

        $tmp = $row;
    } 
}

上面的代码让我得到了我想要的东西。我想知道是否有任何算法或良好的查询更有效地找到相同的结果?

我希望这个问题比以前更加清晰,我对问题的理解要好一些。

1 个答案:

答案 0 :(得分:1)

您可以选择结束时间和开始时间之间的差异与您的间隔匹配的行,并按您所需的开始时间和行的开始时间之间的差异排序。

例如:

select id, startRange, endRange from table_name_here 
where (tstEnd-tstStart)=(1388397600-1388394000) 
order by abs(1388394000-tstStart) asc limit 4;

英文: 选择间隔(tstEnd-tstStart)等于您请求的间隔的行,并按您请求的开始时间与行的开始时间之间的差值的绝对值排序,最小差异为第一行和最多四行。

注意:

使用整数而不是日期更容易;我看到你已经在表中存储了一个整数时间戳。将您的请求开始/结束转换为整数。对于此示例,请求start = 1388394000并且请求end = 1388397600

为了便于说明,我有(tstEnd-tstStart)=(1388397600-1388394000),但为了提高效率,您应该在代码中计算一次请求的时间间隔(1388397600-1388394000),而不是每行。

确保使用占位符,而不是将值直接粘贴到查询字符串中。