1

我无法在我正在开发的网站上实现搜索功能。

搜索表单有两个字段,用户想要租用车辆的开始日期和结束日期。

在数据库中,我有两张表,一张用于车辆,另一张用于可用日期。

Table: cars
 - car_id (int)
 - name (varchar)
 - description (varchar)

Table: cars_availability
 - car_id (int)
 - date (datetime)
 - status (int) // 1: available 2: booked

cars_availability中的每一行代表相关汽车可供出租或预订的一天。

问题:

如果用户搜索从 2013 年 2 月 5 日到 2013 年 2 月 8 日可用的汽车,想做一个查询以选择用户选择中所有日子都可用的所有汽车。

我目前未完成的解决方案:

我知道我可以使用这样的东西来迭代所有的日子

$begin = new \DateTime( date('Y-m-d', strtotime($data['rent_start'])));
$end = new \DateTime( date('Y-m-d', strtotime($data['rent_end'])));
$end = $end->modify( '+1 day' ); 

$interval = \DateInterval::createFromDateString('1 day');
$period = new \DatePeriod($begin, $interval, $end);

$available_cars = array();

foreach ( $period as $dayTime ){

    // query the cars and joining the cars_availabilty table

    $item = DB::select('cars.*')
    ->from('cars')
    ->join('cars_availability')->on('cars_availability.item_id', '=', 'cars.item_id')
    ->where('items_availability.date', '=', $dayTime->format("Y-m-d H:i:s"))
    ->and_where('items_availability.status', '=', 1)
    ->execute()->as_array();

    if(count($item) > 0){

      if(isset($available_cars[$item[0]['item_id']])){

        $available_cars[$item[0]['item_id']][] = $item[0];

      }else{

        $available_cars[$item[0]['item_id']] = array();
        $available_cars[$item[0]['item_id']][] = $item[0];
      }
    }

}

在此之后,我将拥有一系列车辆,这些车辆可能全天都可用,但我需要做一些额外的数学运算才能找到答案。

我想知道这个问题是否有一些更优雅的解决方案,也许使用更好的查询。

如果您能给我任何反馈,我将不胜感激。

谢谢

4

1 回答 1

2

这实际上是一个相当健全的查询设置。就个人而言,我建议遵循@inhan 的建议,特别是如果事实证明汽车可以在更短的时间内预订(几小时?)。然而,由于极端情况,查询编写起来有点复杂(如果你看看这里,你应该找到相关的例子)。

不幸的是,我无法说明这如何适合您的框架,但 SQL 可能如下所示:

SELECT Cars.car_id, Cars.name, Cars.description
FROM Cars
JOIN (SELECT car_id
      FROM Cars_Availability
      WHERE `date` >= '2013-02-05'
            AND `date` < '2013-02-09'
            AND status = 1
      GROUP BY car_id
      HAVING COUNT(*) = DATEDIFF('2013-02-09', '2013-02-05')) Available
  ON Available.car_id = Cars.car_id

(有一个SQL Fiddle 示例
此查询假定每天只有一个条目,否则会中断。基本上,它抓取大于/等于开始日期且小于“结束”日期的每个“可用”行(日期/时间/时间戳......很复杂;本文处理特定于 SQL Server 的问题,但基本概念适用),并确保它们之间的天数有一个。大多数情况下,您正在寻找该HAVING子句。
给定正确的索引Cars_Availability,它甚至可能不会上桌,这也使它成为一个很好的表现者。

于 2013-02-01T00:55:36.617 回答