【问题标题】:Complex SQL query in order retrieve the available beds in a given timeframe matched to rooms in a reservation system复杂的 SQL 查询,以检索与预订系统中的房间匹配的给定时间范围内的可用床位
【发布时间】:2015-05-30 13:30:51
【问题描述】:

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

不知何故,我的查询似乎部分有效,但不幸的是它返回了一些错误的行。从小提琴中可以看出,例如,由于 WHERE NOT (ro.status = 0) 子句,不应返回房间 1 中的床,因为房间 1 的 room_status 设置为 0(房间不可用例如由于清洁)。

使用的表格是:

床(包含所有床,与具有 FK room_id 的房间匹配) 房间(包含所有房间,房间可以被禁用 eq. 用于通过 room_status 字段进行清洁。如果房间被禁用,则所有相关联的床都不可用) 预订(包含所有预订) 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 http://sqlfiddle.com/#!9/cca72/4

提前谢谢你

【问题讨论】:

  • left joins 似乎是不必要的,因为where 子句将它们转换为内部连接。另外,我要删除 SQL Server 标记,因为语法显然是 MySQL。
  • 感谢您的提示。是的,这就是重点,我基本上需要将每张床与它的房间名称和房间状态相匹配。在那之后,我要整理床,因为 ro.status=0 或在 $start 和 $end 日期之间不可用而无法使用这些床

标签: php mysql sql


【解决方案1】:

我想你的问题是日期比较。您正在将日期作为字符串进行比较。虽然你不应该这样做,但如果格式是 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 注入和防止数据库中出现运行时错误的好习惯。)

您的查询可能还有其他问题。

【讨论】:

    【解决方案2】:

    找到问题了,大错特错..

    我做到了

    LEFT JOIN room ro ON ro.id = b.id 
    

    但这应该是

    LEFT JOIN room ro ON ro.id = b.room_id
    

    【讨论】:

      猜你喜欢
      • 2016-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多