我正在开发一个预订系统,我需要在给定的时间范围内选择所有可用的床位,并将它们与他们所在的房间相匹配。
不知怎的,我的查询似乎部分工作,但遗憾的是它返回了一些错误的行。正如在小提琴中可以看到的那样,由于 WHERE NOT(ro.status = 0)子句,因此房间1中的床不应返回,因为房间1的room_status设置为0(房间不可用)适当的清洁例如)。
使用的表是:
床(包含所有床铺,与FK room_id房间相匹配) 房间(包含所有房间,房间可以被禁用eq。在room_status字段清理purpoes。如果房间被禁用,所有相关的床都不可用) 预订(包含所有预订) reservation_bed(与预订的某些床位相匹配)。
我的查询如下:
SELECT b.id AS bed_id, b.name AS bed_name, b.room_id AS room_id, ro.name AS room_name, ro.status AS room_status
FROM bed b
LEFT JOIN room ro ON ro.id = b.id
WHERE NOT (ro.status = 0) AND b.id NOT IN(SELECT rb.bed_id FROM reservation_bed rb
LEFT JOIN reservation r ON r.id = rb.reservation_id
WHERE r.end BETWEEN str_to_date('$start', '%d.%m.%Y') AND str_to_date('$end', '%d.%m.%Y') OR
str_to_date('$start', '%d.%m.%Y') BETWEEN r.start AND r.end
ORDER BY b.room_id
SQLFiddle here http://sqlfiddle.com/#!9/cca72/4
提前谢谢
答案 0 :(得分:0)
我想你的问题是日期比较。您将日期比较为字符串。虽然您不应该这样做,但如果格式为YYYY-MM-DD则没有问题。相反,使用 date 变量正确比较日期:
WHERE r.end BETWEEN str_to_date('$start', '%d.%m.%Y') AND str_to_date('$end', '%d.%m.%Y') OR
str_to_date('$start', '%d.%m.%Y') BETWEEN r.start AND r.end
实际上,不是在查询中插入字符串,而是应该插入参数,并且可以为这些类型指定日期 - 从而消除了查询本身中类型转换的需要。 (并且,这是避免SQL注入和防止数据库中的运行时错误的好习惯。)
您的查询也可能有其他问题。
答案 1 :(得分:0)
发现问题,错误的错误..
我做了
LEFT JOIN room ro ON ro.id = b.id
但这应该是
LEFT JOIN room ro ON ro.id = b.room_id