复杂的SQL查询,以便在与预订系统中的房间匹配的给定时间范围内检索可用的床位

时间:2015-05-30 13:30:51

标签: php mysql sql

我正在开发一个预订系统,我需要在给定的时间范围内选择所有可用的床位,并将它们与他们所在的房间相匹配。

不知怎的,我的查询似乎部分工作,但遗憾的是它返回了一些错误的行。正如在小提琴中可以看到的那样,由于 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

提前谢谢

2 个答案:

答案 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