我在会议室预订系统上工作,我无法确定是否在规定的时间范围内拍摄了房间,我使用当前日期格式并在表格中将类型设置为DATETIME
:YYYY-MM-DD HH:II:SS
这是我目前的代码:
//Function to check if a booking exists:
function bookingExist($DateStart, $DateEnd, $RoomNo) {
global $DB;
$sql = "SELECT * FROM bookings WHERE date_start = :dateStart AND date_end = :dateEnd AND room_no = :roomNo";
$Q = $DB->prepare($sql);
$Q->bindParam(':dateStart', $DateStart);
$Q->bindParam(':dateEnd', $DateEnd);
$Q->bindParam(':roomNo', $RoomNo);
$Q->execute();
if ($Q->rowCount()) {
//A record exists...
return true;
} else {
//no record exists
return false;
}
}
有没有办法在sql查询中执行此操作?
示例:房间A在2016-03-31 15:00:00和2016-03-31 17:30:00之间预订,然后用户尝试为2016-03-31 16的房间A创建新预订: 30:00 - 2016-03-31 17:00:00,由于预订,应该返回1条记录
答案 0 :(得分:5)
SELECT *
FROM bookings
WHERE
(
:dateStart BETWEEN date_start AND date_end
OR :dateEnd BETWEEN date_start AND date_end
OR date_start BETWEEN :dateStart AND :dateEnd
)
AND room_no = :roomNo
如果在给定时间内没有预订房间,这将为您提供零行:dateStart - :dateEnd。
:dateStart BETWEEN date_start AND date_end
会检查它是否已在开始时间预订,:dateEnd BETWEEN date_start AND date_end
会检查是否在结束时间预订了它,而最后一个date_start BETWEEN :dateStart AND :dateEnd
也是重要的,它会检查是否有房间是介于两者之间(例如较短的时期)
编辑:或时而不是AND;)
EDIT2:要排除开始和结束时间,您必须展开BETWEEN
关键字并使关系仅为<
:
SELECT *
FROM bookings
WHERE
(
(date_start < :dateStart AND :dateStart < date_end)
OR (date_start < :dateEnd AND :dateEnd < date_end)
OR (:dateStart < date_start AND date_start < :dateEnd)
)
AND room_no = :roomNo
答案 1 :(得分:0)
在sql查询中使用BETWEEN怎么样?您需要设置要检查的日期/时间参数(这将是给定示例中第二个用户请求的日期/时间)。
$firstDate = //start of time period you are checking;
$lastDate = //end of time period you are checking;
$Q->bindParam(':firstDate ', $firstDate );
$Q->bindParam(':lastDate ', $lastDate );
$sql = "SELECT * FROM bookings WHERE :date_start BETWEEN :firstDate AND :lastDate AND room_no = :roomNo";
答案 2 :(得分:0)
[booking1 10/7/21 11:00 - 11:30]
[---new--- 10/7/21 11:30 -
11:20]
[预订 2 10/7/21 12:00 - 12:30]
如果预订不存在,您可以使用以下语法插入预订:
-- new booking [b1][new][b2]
SET @s = '2021-07-10 11:30:00';
SET @e = '2021-07-10 12:00:00';
INSERT INTO Appointments
(col1, col2, starts, ends)
SELECT 'some data', 'some data', @s, @e
WHERE NOT EXISTS
(SELECT id FROM Appointments -- search for collision points
WHERE
((starts <= @s AND @s < ends)
OR (starts < @e AND @e <= ends)
OR (@s <= starts AND starts < @e)
))
AND (1=1) -- some other conditions
;
如果在 WHERE NOT EXISTS (SELECT...)
语句中没有返回数据,INSERT
将继续。如果 SELECT
至少返回一行,INSERT
将不会被执行。
以上示例允许预订开始和结束与新预订重叠。请注意,新预订从 11:30 开始。同时在 11:30 结束预订,这已经在我们的虚构数据库中。同样适用于新预订结束的时间 - 它也与预订 nr 2 的开始重叠,这是可以的。上述查询适用于这种情况。如果您改用 BETWEEN,这将不包括这种情况。
在大多数情况下,这会产生意想不到的结果:
WHERE NOT EXISTS
(SELECT id FROM your_table
WHERE
((@s BETWEEN starts AND ends
OR @e BETWEEN starts AND ends
OR starts BETWEEN @s AND @e))
AND (1=1)) -- replace (1=1) with other mandatory conditions
LIMIT 1;
这将产生正确的结果:
WHERE NOT EXISTS
(SELECT id FROM your_table
WHERE
((starts <= @s AND @s < ends)
OR (starts < @e AND @e <= ends)
OR (@s <= starts AND starts < @e))
AND (1=1)) -- replace (1=1) with other mandatory conditions
LIMIT 1; conditions