餐厅sql reserervations与基本计划可用性和例外

时间:2013-12-02 01:41:03

标签: php mysql sql datetime

我正在开展一个项目,用户可以在这里预订餐厅,但仅限于餐厅允许的日期。餐厅还可以设置在特定时间有多少座位。

因此,餐厅可以提供每周格式化的时间表,但也可以提供例外(如假期)。

我需要的是完整表示给定时间范围内的可用范围和座位。

所以例如一家餐馆有一个周的时间表,说每个工作日他们有10个座位,但也有几个保留我需要这样的输出 所以我可以生成一个日历,用户可以看到餐厅的可用性。

+---------------------+---------------------+-----------+
|        start        |         end         | available |
+---------------------+---------------------+-----------+
| 2013-02-14 08:00:00 | 2013-02-14 17:00:00 |        10 |
| 2013-02-15 08:00:00 | 2013-02-15 12:00:00 |         8 | <= 2 reservations
| 2013-02-15 12:00:00 | 2013-02-16 15:00:00 |         4 | <= 6 reservations
| 2013-02-15 15:00:00 | 2013-02-16 15:00:00 |         7 | etc...
| 2013-02-16 15:00:00 | 2013-02-16 17:00:00 |         4 |
| 2013-02-17 08:00:00 | 2013-02-17 17:00:00 |        10 |
| 2013-02-18 12:00:00 | 2013-02-18 18:00:00 |        10 |
+---------------------+---------------------+-----------+

1 个答案:

答案 0 :(得分:0)

我们需要两组数据:一次可用的时间和可用的座位;以及现有预订清单。

CREATE TABLE IF NOT EXISTS `availability` (
`dayOpen` date NOT NULL,
`open` time NOT NULL,
`close` time NOT NULL,
`seats` tinyint unsigned NOT NULL,
PRIMARY KEY (`dayOpen`)
) ;

CREATE TABLE IF NOT EXISTS `reservations` (
`reservationsid` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`dayOpen` date NOT NULL,
`start` time NOT NULL,
`seatsUsed` tinyint unsigned NOT NULL,
PRIMARY KEY (`reservationsid`)
) ;

我将假设您的预订必须从小时开始,持续59分钟。这意味着我们的结果集将是使用座位数的小时列表。然后拉出可用时间并循环查看每小时的列表以及可用的座位数。

<?php

  $pdoHandle = new PDO($dsn,$user,$password);

  // Get all the used seats. Add WHERE with date range to limit results
  $query = 'SELECT dayOpen, start, SUM(seatsUsed) as seatsBooked FROM reservations GROUP BY dayOpen, start';
  $results = $pdoHandle->query($query);
  $allSeatsUsed = array();
  while ( $row = $results->fetch(PDO::FETCH_OBJ) )
  {  $allSeatsUsed[ $row->dayOpen ][ $row->start ] = $row->seatsBooked;  }

  // GET all possibile seats. Add WHERE with date range to limit results
  $query = 'SELECT * FROM availability ORDER BY dayOpen';
  $results = $pdoHandle->query($query);
  $allSeatsPossible = $results->fetchall(PDO::FETCH_OBJ);

  // got through each day to limit results to only open seats
  $finalOpenList = array();
  foreach ( $allSeatsPossible as $dayOpen )
  {
    $finalOpenList[ $dayOpen->dayOpen ] = array();
    $open = new DateTime($dayOpen->open);
    $close = new DateTime($dayOpen-close);
    $interval = new DateInterval('P1H');
    $todaysSlots = new DatePeriod($open,$interval,$close);
    foreach ( $todaysSlots as $slot )
    {
      if ( $allSeatsUsed[ $dayOpen->dayOpen ][ $slot->format('H:i:s') ] < $dayOpen->seats )
      {  $finalOpenList[ $dayOpen->dayOpen ][ $slot->format('H:i:s') ] = 
            $dayOpen->seats - 
            $allSeatsUsed[ $dayOpen->dayOpen ][ $slot->format('H:i:s') ];  }
    }
  }

  // $finalOpenList contains a list of days, with each day 
  // holding a list of hours and the number of slots left per hour
  foreach ( $finalOpenList as $day => $hours )
  {
    $day = new DateTime($day);
    print '<p>'.$day->format('M j, Y').': ';
    if ( sizeof($hours) == 0 )
    {  print 'All seats booked.</p>';  }
    else
    {
      print '</p><ul>';
      foreach ( $hours as $hour=>$seatsLeft )
      {  print '<li>'.$hour.': '.$seatsLeft.' seats available.</li>';  }
      print '</ul>';
    }
  }

?>