检查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
定义的范围重叠的checkin
和checkout
在任何方式定义的范围,然后房间被黄牌警告。否则,它是免费的。
这意味着:
- 如果
$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查询
(请记住,还有对皮肤有猫不止一种方法,可以这么说,我只是提供与你已经有尽可能多的保留的例子。尽可能。再一次,我还假设checkin
,checkout
,$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'))
有一些好的想法在这里: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'
...它到达上面给出的解决方案。
好答案............ – 2016-06-29 11:24:56
嗨,感谢您的回复。 你可以请写一个模拟的SQL,以便我可以跟随,因为我不是很擅长编写SQL(MySQL正好) 再次感谢 – 2012-01-18 17:33:46
这是一个很好的抓住!该查询检查范围的两端,但中间怎么样?换句话说,假设客户想要预订4晚的房间,但它已经预订了一晚的中间房间?预订登记将大于请求的$ check_in,并且预订结账将低于请求的$ check_out,但房间不可用....对吧? – Aerik 2012-01-18 17:47:16
@Aerik这是一个很好的抓住自己 - 我会相应地更新我的答案。 – 2012-01-18 17:49:30