使用MYSQL选择日期之间的行?

时间:2013-09-09 14:03:07

标签: php mysql sql

我对一些MYSQL有一点问题。

我需要能够检查是否已经在假日房间预订了一段时间。

我的数据库使用DATETIME字段,如下所示:

Database image link, as my rep is low

我有一个类似的查询:

SELECT * FROM `caravanavail1` 
WHERE (`checkIn` BETWEEN '2014-01-07 14:00:00' AND '2014-01-08 10:00:00') 
OR (`checkOut` BETWEEN '2014-01-07 14:00:00' AND '2014-01-08 10:00:00')

我将永远传递两个日期,但有时日期可能会在很多方面发生冲突:

  1. checkIn可能在另一个假期的中间,checkOut可能没有。
  2. checkOut可能在另一个假期中间,checkIn可能没有。
  3. 他们可能与另一个假期相同。
  4. 我提供的checkIn和checkOut日期可能会在另一个预订中。
  5. 我一直在摸不着头几天,任何人都可以帮我修复上面的SQL代码(我更喜欢单个查询,而不是两个)来返回我需要的东西吗?

3 个答案:

答案 0 :(得分:5)

        |________|      // date to book
    |______|            // condition 1
              |______|  // condition 2
          |____|        // condition 3 
    |________________|  // condition 4

如果这4个条件中的任何一个导致连续,这意味着无法完成预订。

$in =  '2014-01-07 14:00:00';
$out = '2014-01-08 10:00:00';

SELECT * 
FROM `caravanavail1` 
WHERE 
  (`checkIn` <= '$in' AND `checkOut` <= '$out') // condition 1
  OR 
  (`checkIn` >= '$in' AND `checkOut` >= '$out')  // condition 2
  OR 
  (`checkIn` >= '$in' AND `checkOut` <= '$out') // condition 3
  OR 
  (`checkIn` <= '$in' AND `checkOut` >= '$out') // condition 4

正如Marc B所说,这可以进一步简化: 条件的所有签到时间 您要预订的结账时间所有条件的签出时间 >签到时间之后想要预订

归结为:

SELECT * 
FROM `caravanavail1` 
WHERE 
  (`checkIn` < '$out' AND `checkOut` > '$in')

有时可视化:)

答案 1 :(得分:4)

考虑这个图。 xy是相关的签到/结帐时间,pq是数据库中的签入/结帐时间。这两个日期范围可以有多种方式重叠:

     x   y
p  q               // complete non-overlap, no conflict
   p  q            // partial overlap, conflict
      p q          // partial overlap, conflict
       p  q        // partial overlap, conflict
           p   q   // complete non overlap, no conflict

如果你绘制逻辑,你会发现

 if (q >= x) && (p <= y) {
       ... there is a conflict
 }

劝说你的基地。

答案 2 :(得分:2)

为了达到重叠范围的条件,更容易考虑没有重叠的地方然后反转条件。 如果一个完全在另一个之前或之后,会重叠两个范围。

在SQL中,这意味着结帐日期在给定的签​​入日期之前,或者签入日期在给定的结帐日期之后:

SELECT * FROM `caravanavail1` WHERE NOT (checkOut <= '$in' OR checkIn >= '$out')

您可以将其简化为:

SELECT * FROM `caravanavail1` WHERE checkOut > '$in' AND checkIn < '$out'