我正在尝试找到正确的查询来检查MySQL表中的日期和时间范围是否重叠,这是表格:
id pickup_date pickup_time return_date return_time
1 2016-05-01 12:00:00 2016-05-31 13:00:00
2 2016-07-01 12:00:00 2016-07-04 15:00:00
以下是有关每个预订的数据,需要根据“预订”表进行检查:
pickup_date = '2016-04-01';
pickup_time = '12:00:00'
return_date = '2016-05-01';
return_time = '13:00:00'
使用此数据,预留与数据库中的预留重叠。请注意:新预订可以是过去或将来。
编辑(由spencer7593提议,这是迄今为止的工作版本):
SET @new_booking_pickup_date = '2016-04-01';
SET @new_booking_pickup_time = '12:00:00';
SET @new_booking_return_date = '2016-05-01';
SET @new_booking_return_time = '13:00:00';
SELECT * FROM Reservation WHERE NOT
( CONCAT(@new_booking_pickup_date,' ',@new_booking_pickup_time) > CONCAT(return_date,' ',return_time) + INTERVAL 0 DAY OR CONCAT(@new_booking_return_date,' ',@new_booking_return_time) < CONCAT(pickup_date,' ',pickup_time) + INTERVAL 0 DAY);
,所以这个查询会产生:
id pickup_date pickup_time return_date return_time
1 2016-05-01 12:00:00 2016-05-31 13:00:00
答案 0 :(得分:1)
很容易确定某个特定时期是否与另一个时期重叠。
为了便于表达比较,对于时段1,我们将开头和结尾用b1和e1表示。对于时期2,b2和e2。
如果满足以下条件,则不会重叠:
b1 > e2 OR e1 < b2
(我们可以狡辩是否将b1和e2的相等视为重叠,并根据需要进行调整。)
如果存在重叠,则该测试的否定将返回TRUE
NOT (b1 > e2 OR e1 < b2)
因此,要查明是否存在与建议期间重叠的行,我们需要一个测试是否返回行的查询...
假设我们要检查的表格有st
列和et
(DATETIME),表示每个句点的开头和结尾。
查找与b1
和e1
SELECT t.* FROM t WHERE NOT (b1 > t.et OR e1 < t.st)
因此,对于只检查是否存在重叠行的查询,我们可以执行以下操作:
SELECT EXISTS (SELECT 1 FROM t WHERE NOT (b1 > t.et OR e1 < t.st))
这非常简单。
当我们将日期时间的date
和time
组件的(无法解释的)拆分调整为单独的列时,它看起来会变得复杂得多(如图所示)问题)。
将单独的日期和时间值组合在一起成为DATETIME
数据类型的单个值只是一件简单的事。
我们需要做的就是将上面的查询替换为适当的转换,例如
st => CONCAT(pickup_date,' ',pickup_time) + INTERVAL 0 DAY
et => CONCAT(return_date,' ',return_time) + INTERVAL 0 DAY
b1
和e1
相同。
做出替代,提出最终查询,留给任何人决定将日期和时间存储为单独的列是一个好主意。