检查MySQL中的日期范围冲突

检查MySQL中的日期范围冲突

问题描述:

我在写一个酒店预订系统。大量的研究(包括堆栈溢出)后,我写了这个SQL找出免费客房:检查MySQL中的日期范围冲突

SELECT 
* 
FROM room 
WHERE 
    room_id NOT IN (
     SELECT room_id 
     FROM bookings 
     WHERE 
       checkin <= '$check_in' 
      AND checkout >= '$check_out' 
    ) 

,但问题是它没有考虑时间检查是12点00分00秒和退房是11点59分00秒

它也没有给出像日期范围内的正确查询它不工作就像如果我从15-18预订单个房间谁是数字是501.如果我再次运行查询17-19这个房间似乎是免费的,但在它应该被占领。

任何人都可以提出一个非常好的和有效的SQL,它会得到准确的日期,所以没有冲突会发生预订系统,因为系统将实际执行,所以错误会导致许多问题。

在此先感谢

您遇到的问题是您的查询不够健壮。当你打破的问题,你有什么是这样的:

如果$check_in$check_out定义的范围重叠的checkincheckout任何方式定义的范围,然后房间被黄牌警告。否则,它是免费的。

这意味着:

  • 如果$check_in> = checkin$check_in < = checkout,房间BOOKED
  • OR如果$check_out> = checkin$check_out < = checkout,房间是预订
  • OR如果$check_in < = checkin$check_out> = checkout,房间BOOKED

所以,你需要在你的子查询来表示这两种方案,以获取您的信息寻找。

此外,你会希望使用datetime作为比较,而不仅仅是time,否则你会有副作用。

编辑:SQL查询

(请记住,还有对皮肤有猫不止一种方法,可以这么说,我只是提供与你已经有尽可能多的保留的例子。尽可能。再一次,我还假设checkincheckout$check_in$check_out都将解析为datetime类型)

SELECT * 
FROM room 
WHERE room_id NOT IN 
(SELECT room_id 
FROM bookings 
WHERE 
    (checkin <= '$check_in' AND checkout >= '$check_in') OR 
    (checkin <= '$check_out' AND checkout >= '$check_out') OR 
    (checkin >= '$check_in' AND checkout <= '$check_out')) 
+0

嗨,感谢您的回复。 你可以请写一个模拟的SQL,以便我可以跟随,因为我不是很擅长编写SQL(MySQL正好) 再次感谢 – 2012-01-18 17:33:46

+3

这是一个很好的抓住!该查询检查范围的两端,但中间怎么样?换句话说,假设客户想要预订4晚的房间,但它已经预订了一晚的中间房间?预订登记将大于请求的$ check_in,并且预订结账将低于请求的$ check_out,但房间不可用....对吧? – Aerik 2012-01-18 17:47:16

+0

@Aerik这是一个很好的抓住自己 - 我会相应地更新我的答案。 – 2012-01-18 17:49:30

有一些好的想法在这里:http://forums.digitalpoint.com/showthread.php?t=63746

此外,什么列类型是你使用您的入住和退房?你确定你在$ check_in和$ check_out中正确地传递了格式化的值吗?

我认为这可能让你在正确的方向开始......

SELECT R.* 
FROM room AS R 
    LEFT OUTER JOIN bookings AS B USING (room_id) 
WHERE B.room_id IS NULL 
     OR (B.checkout < '$check_in' 
      AND B.checkin > '$check_out') 

你原来的逻辑是非常接近的,你只需要交换'$check_in''$check_out'值。即:

SELECT * 
FROM room 
WHERE room_id NOT IN 
(
    SELECT room_id 
    FROM bookings 
    WHERE checkin <= '$check_out' AND checkout >= '$check_in' 
) 

布赖恩·德里斯科尔的回答论点集中在构成预订冲突,所以场景:

---------------|-----Booked-----|--------------- 
     |----A1----| 
          |----A2----| 
        |--A3--| 
      |----------A4----------| 

Case A2 & A3: checkin <= '$check_in' AND checkout >= '$check_in' 
Case A1 & A3: checkin <= '$check_out' AND checkout >= '$check_out' 
Case A4:  checkin >= '$check_in' AND checkout <= '$check_out' 

但是构成没有冲突senarios要简单得多。只有两个:

---------------|-----Booked-----|--------------- 
    |----B1----|        
            |----B2----| 

Case B1: checkin > '$check_out' 
Case B2: checkout < '$check_in' 

所以那里有一个订票和潜在的预订之间没有冲突可以用这个SQL来表达情况:

checkin > '$check_out' OR checkout < '$check_in' 

要检查是否存在冲突,而不是,我们只需要否定这一点。因此,使用DeMorgans定律,否定是:

checkin <= '$check_out' AND checkout >= '$check_in' 

...它到达上面给出的解决方案。

+0

好答案............ – 2016-06-29 11:24:56