0

我正在做一个房屋租赁的预订页面。

我有一个日期选择器,我的用户提交了一个 UNIX 日期时间:到达和离开日期。
在 mySQL 上,我有一个带有“season_start”日期(YYYY-mm-dd)、“season_end”日期和“每天价格”的不同季节的房子。

$seasons_select="SELECT id,season_start,season_end,daily_price FROM ".T_ITEM_SEASONS." WHERE id_item=".ID_ITEM." ORDER BY season_start ";
$res_seasons=mysql_query($seasons_select) or die("Error getting states");
$arrival_date = date('d-m-Y', $arrival_date);
$departure_date = date('d-m-Y', $departure_date);
 while ($seasons_row=mysql_fetch_assoc($res_seasons)){
  $start_date = date('d-m-Y', strtotime($seasons_row["season_start"]));
  $end_date = date('d-m-Y', strtotime($seasons_row["season_end"]));
  $current_date = $start_date;
  while($current_date != $end_date){
   $current_date = date("d-m-Y", strtotime("+1 day", strtotime($current_date)));
   $match_date = $arrival_date;
   while($match_date != $departure_date){
    $match_date = date("d-m-Y", strtotime("+1 day", strtotime($match_date)));
    if ($current_date==$match_date){ 
     echo $current_date.' This is one of the days! <br />';
    }       
   }    
  } 
 }

如果用户到达/离开期间内的日期在一个或多个季节内,最佳匹配方法是什么?

我的代码有点工作......
我得到了我想要的答案,但在它之后出现“致命错误:超过 30 秒的最大执行时间”

4

2 回答 2

1

如果用户到达/离开期间的日期在一个或多个季节内,那么匹配的最佳方法是什么?

好吧,的看起来有点糟糕:-)

我想说,让 MySQL 来完成这项工作——首先只选择那些你想要的记录。

要检查单个日期是否在“季节”内,您必须检查它是否大于季节开始且小于季节结束。

要获取到达/离开期间的任何一天属于的所有季节,您必须检查四种情况:

|是季节的开始和结束,A是选择的到达和D离开日期。)

S: -------------------|-----------------|------------------
1. ---------------A--------------------------D-------------
2. ---------------A-----------------D----------------------
3. -----------------------A---------D----------------------
4. -----------------------A------------------D-------------
  1. 季节完全落入选定的时期。

  2. 赛季开始前到达,结束前出发。

  3. 赛季开始后到达,结束前出发。

  4. 赛季开始后到达,赛季结束后出发。

(之前和之后总是意味着包括,所以真的是之前/之后和之后。)


放入一个查询,可能看起来像这样,2013-05-04作为到达和2013-07-04离开日期:

SELECT id, season_start, season_end, daily_price FROM table
WHERE id_item = 1234 AND (
   ('2013-05-04' <= season_start AND '2013-07-04' >= season_end) OR
   ('2013-05-04' <= season_start AND '2013-07-04' <= season_end) OR
   ('2013-05-04' >= season_start AND '2013-07-04' <= season_end) OR
   ('2013-05-04' >= season_start AND '2013-07-04' >= season_end)
)
ORDER BY season_start

由于您说您将用户输入作为 Unix 时间戳接收,因此您可以date()在将它们插入查询之前使用 PHP 对其进行格式化,或者您可以FROM_UNIXTIME(123456789, '%Y-%M-%D')在这些地方使用 MySQL。

season_start并且您应该在列和season_end(每个索引一个)上创建一个索引(如果还没有),以获得更好的性能。


编辑:正如萨尔曼在评论中提到的这个答案中所指出的那样,两个条件(以及我在应用布尔逻辑方面的更多创造力)足以检查,因此 WHERE 子句可以简化为

WHERE id_item = 1234 AND
  ('2013-05-04' <= season_end) and ('2013-07-04' >= season_start)
于 2013-05-04T19:12:12.553 回答
0

与其遍历一个季节的所有日子来查看给定日期是否在其范围内,不如尝试如下查询。

"SELECT id,season_start,season_end,daily_price FROM ".T_ITEM_SEASONS." WHERE id_item=".ID_ITEM." AND season_start <= $arrival_date AND season_end >= $departure_date ORDER BY season_start ";

其中 $arrival_date 和 $departure_date 是您的日期选择器中的值。

这样您就不必遍历整个季节的所有日子来查找匹配的日期。

需要注意的一点 - 在到达和离开日期跨越季节(在一个季节到达并在另一个季节离开)的情况下考虑所需的结果 上述查询将仅返回到达和离开日期在同一季节内的行。

于 2013-05-04T19:27:09.220 回答