我有这个预订请求: 从2016年2月13日起 - 09:00h到15.02.2016 09:00h租车2天
在确认可用性之前,我想检查我的数据库哪些车辆将忙/已经预留。
我提出这个问题:
select id,modelname from res_reservations
where resnumber!="9915" and datestart > now() and
(datestart BETWEEN "2016-02-13 09:00:00" AND "2016-02-15 09:00:00" or
dateend BETWEEN "2016-02-13 09:00:00" AND "2016-02-15 09:00:00")
order by id ASC
在数据库res_reservations中我有以下记录:
#id #modelname #datestart #dateend
9912 Volvo 2016-02-25 11:00:00 2016-02-29 09:30:00
9911 Renault 2016-02-12 19:15:00 2016-02-24 12:00:00
9913 Opel 2016-02-16 12:00:00 2016-02-18 12:00:00
我的查询返回此期间没有车辆忙,但这无效,因为ID#9911将在2016-02-12 19:15:00 - 2016-02-24 12:00:00之间保留
如何获得该期间已预订的所有车辆。
感谢您提供任何帮助和建议。
为了澄清,我有一个严肃的理由在数据库中搜索预订车,但不是免费的......
答案 0 :(得分:3)
你的逻辑错误。您只能检测到部分重叠,并且不允许完全重叠。例如给出新预订的两个日期A + B,以及数据库中现有的X + Y日期,您最终会得到以下可能性:
x y
-------------
1 a b | | - no overlap
2 a b | - b = x
3 a | b | - x < b < y
4 a | b - b = y
5 a | | b - a < x && b > y
6 a b | - full overlap
7 a b - a = x
8 a | b - yada yadayada
9 |a b|
10 | a | b
11 | a b
12 | | a b
您只检查a或b在X / Y日期之间的条件,这些条件并未涵盖所有可能性,尤其是#5
答案 1 :(得分:1)
我认为这是一个逻辑问题。查询应如下:
select id,modelname
from res_reservations
where resnumber!="9915" and datestart > now() and
("2016-02-13 09:00:00" BETWEEN datestart AND dateend or
"2016-02-15 09:00:00" BETWEEN datestart AND dateend)
order by id ASC
答案 2 :(得分:1)
您的问题是您正在捕获在预订时间内开始或结束的预订,而不是在之前和之后开始的预订。
您想要的逻辑是找到其他预订,其中开始位于您正在查看的期间结束之前,结束位于期间开始之后。这应该是所有重叠的预订。
SELECT id,modelname FROM res_reservations
WHERE resnumber!="9915" AND datestart > NOW() AND
(datestart < "2016-02-15 09:00:00" AND
dateend > "2016-02-13 09:00:00" )
ORDER BY id ASC
答案 3 :(得分:1)
我不确定这是否是您所追求的 - 它正在使用变量,因为我从cmd行运行它,但很容易替换静态值或PHP变量而不是@var
等
/*
create table if not exists `res_reservations` (
`id` int(10) unsigned not null auto_increment,
`modelname` varchar(50) not null default '0',
`datestart` datetime not null,
`dateend` datetime not null,
primary key (`id`)
) engine=innodb auto_increment=7 default charset=utf8;
insert into `res_reservations` (`id`, `modelname`, `datestart`, `dateend`) values
(1, 'volvo', '2016-02-25 11:00:00', '2016-02-29 09:30:00'),
(2, 'renault', '2016-02-12 19:15:00', '2016-02-24 12:00:00'),
(3, 'opel', '2016-02-01 12:00:00', '2016-02-10 12:00:00'),
(4, 'ferrari', '2016-02-11 15:45:00', '2016-02-13 07:30:00'),
(5, 'jaguar', '2016-02-14 18:30:00', '2016-02-24 07:00:00'),
(6, 'austin7', '2016-02-15 10:00:00', '2016-02-15 14:30:00');
*/
/*
select * from `res_reservations`
+----+-----------+---------------------+---------------------+
| id | modelname | datestart | dateend |
+----+-----------+---------------------+---------------------+
| 1 | Volvo | 2016-02-25 11:00:00 | 2016-02-29 09:30:00 |
| 2 | Renault | 2016-02-12 19:15:00 | 2016-02-24 12:00:00 |
| 3 | Opel | 2016-02-01 12:00:00 | 2016-02-10 12:00:00 |
| 4 | Ferrari | 2016-02-11 15:45:00 | 2016-02-13 07:30:00 |
| 5 | Jaguar | 2016-02-14 18:30:00 | 2016-02-24 07:00:00 |
| 6 | Austin7 | 2016-02-15 10:00:00 | 2016-02-15 14:30:00 |
+----+-----------+---------------------+---------------------+
*/
/* assumed to be the dates the customer wants to book a car from/to */
set @ds='2016-02-11 16:00:00';/* new dates */
set @df='2016-02-13 12:00:00';
set @id=9915;
/* show cars that are busy between dates customer wants */
select `id`,`modelname` as 'booked', `datestart` as 'booked-from', `dateend` as 'return-date'
from `res_reservations`
where id!=@id and `datestart` > now() and
(
not( @ds not between `datestart` and `dateend` and @df not between `datestart` and `dateend` )
) or (
@ds > `datestart`
)
order by `id` asc;
/*
+----+---------+---------------------+---------------------+
| id | booked | booked-from | return-date |
+----+---------+---------------------+---------------------+
| 2 | Renault | 2016-02-12 19:15:00 | 2016-02-24 12:00:00 |
| 5 | Jaguar | 2016-02-14 18:30:00 | 2016-02-24 07:00:00 |
+----+---------+---------------------+---------------------+
*/
阅读了你的上一条评论(对延迟道歉,不得不参加会议)我做了一个小小的修改,产生了:
+----+---------+---------------------+---------------------+
| id | booked | booked-from | return-date |
+----+---------+---------------------+---------------------+
| 2 | Renault | 2016-02-12 19:15:00 | 2016-02-24 12:00:00 |
| 3 | Opel | 2016-02-01 12:00:00 | 2016-02-10 12:00:00 |
| 4 | Ferrari | 2016-02-11 15:45:00 | 2016-02-13 07:30:00 |
+----+---------+---------------------+---------------------+
我也试过了,但它产生了同样的结果:
select * from `res_reservations` where `id` not in (
select `id` from `res_reservations` where
id!=@id and `datestart` > now() and not (
( @ds between `datestart` and `dateend` ) or ( @df between `datestart` and `dateend` )
)
)
答案 4 :(得分:0)
我猜你的桌子有datestart和dateend,只有在预订时才会填充(对吗?),说过,我想你可能有错误的条件。
1 - datestart不得介于'2016-02-13 09:00:00'和'2016-02-15 09:00:00'之间,所以:
datestart NOT BETWEEN "2016-02-13 09:00:00" AND "2016-02-15 09:00:00"
2 - 你想检查一本书的日期是否实际上没有阻止汽车预订,所以:
AND /* not OR */
dateend NOT BETWEEN "2016-02-13 09:00:00" AND "2016-02-15 09:00:00"
请评论下来,以便我们对此进行排序。
答案 5 :(得分:0)
您的查询仅在datestart或dateend位于区间内时才有效。它将忽略(datestart&lt; min_interval)和(dateend&gt; max_interval)的情况。
您可以添加另一个OR以包含最后一个案例:
debugString()