使用 MYSQL 选择日期之间的行


Using MYSQL to select rows between dates?

我对一些 MYSQL 有一点问题。

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

我的数据库使用 DATETIME 字段,并按如下方式设置:

数据库图像链接,因为我的代表很少

我有一个这样的查询:

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. 入住可能在另一个假期中间,退房可能不会。
  2. 退房可能在另一个假期中间,而入住可能不会。
  3. 他们可能与另一个假期的日期相同。
  4. 我提供的入住和退房日期可能都在另一个预订中。

我已经为此挠头几天了,任何人都可以帮助我修复上面的SQL代码(我更喜欢一个查询,而不是两个查询)来返回我需要的东西吗?

        |________|      // 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')

有时它有助于可视化:)

考虑这个图。其中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
 }

彪生你的基地。

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

在SQL中,这转换为退房日期在给定的签入日期

之前,或者签入日期在给定的退房日期之后:

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

您可以将其简化为:

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