查询酒店预订的可用房间

时间:2011-05-04 10:25:00

标签: sql

我的任务是创建一个在线酒店预订系统。我遇到的问题是在特定日期范围内查找特定房间类别的可用房间的查询。我的数据库设计涉及4个表。数据库设计如下:

tbl_reservationdetails ( stores the general details of the reservation )
 pk resrvdtl_id (primary key)
 fk client_id (insignificant for now)
    start_date (customer's check-in-date)
    end_date (customer's check-out-date)

tbl_reservation (stores the rooms reserved for a particular reservation )
 pk reserv_id (primary key)
 fk resrvdtl_id (foreign key, to know to whom and when the room should be occupied)
 fk room_id (the room reserved)

tbl_room
 pk room_id (primary key)
    room_number 
 fk room_categId (to know what category this room belongs to)

tbl_roomcategory
 pk room_categId (primary key)
    room_category (description of category.. example: Suite, Superior, Deluxe etc. in my case... there are four categories)

用户输入是日期(开始和结束),以及他想要的房间类别。我对此很新...如何在特定日期查询该类别的可用空间?????

对此的任何回应都将受到高度赞赏......谢谢

2 个答案:

答案 0 :(得分:2)

我可能会将请求的日期范围扩展到相应的日期列表中,然后根据预订记录检查列表中的每个日期以及所请求类别的每个房间。

这是我的SQL Server解决方案,它使用 recursive CTE 来扩展日期范围:

WITH cte_datelist AS (
  SELECT @startdate AS date
  UNION ALL
  SELECT DATEADD(day, 1, date)
  FROM cte_datelist
  WHERE date < @enddate
)
SELECT
  r.room_number,
  MIN(d.date) AS free_from,
  MAX(d.date) AS free_to
FROM cte_datelist d
  CROSS JOIN tbl_room r
  INNER JOIN tbl_roomcategory rc ON r.room_categId = rc.room_categId
  LEFT JOIN tbl_reservation rr ON r.room_id = rr.room_id
  LEFT JOIN tbl_reservationdetails rd ON rr.resrvdtl_id = rd.resrvdtl_id
    AND d.date BETWEEN rd.start_date AND rd.end_date
WHERE rc.room_category = @category
  AND rd.resrvdtl_id IS NULL
GROUP BY
  r.room_number,
  DATEDIFF(day, @startdate, d.date)

此查询的另外两个特定于RDBMS的元素是两个日期函数:

  • DATEADD,在CTE中用于迭代日期范围;

  • DATEDIFF,用于将结果集分组到同一房间的连续日期序列中,而不是

    room_number  date
    1783         27/03/2011
    1783         28/03/2011
    ...          ...
    1783         02/04/2011
    1783         03/04/2011
    1785         15/03/2011
    1785         16/03/2011
    ...          
    1785         01/04/2011
    1785         02/04/2011
    1785         06/04/2011
    1785         07/04/2011
    ...          ...
    1785         10/04/2011
    ...          ...
    

    你可以得到这样的输出:

    room_number  free_from   free_to
    1783         27/03/2011  03/04/2011
    1785         15/03/2011  02/04/2011
    1785         06/04/2011  10/04/2011
    ...          ...         ...
    

答案 1 :(得分:1)

SELECT rooms.room_id
FROM tbl_rooms rooms
INNER JOIN tbl_roomcategory cat ON rooms.room_categId = cat.room_categId
WHERE cat.room_category = [category]
AND rooms.room_id NOT IN (SELECT t1.room_id
                          FROM tbl_room t1
                          INNER JOIN tbl_reservation t2 ON t1.room_id = t2.room_id
                          INNER JOIN tbl_reservationdetails t3 ON t2.resrvdtl_id = t3.resrvdtl_id
                          WHERE NOT ([end date] < t3.start_date OR ([start date] > t3.end_date))

所以我会解释一下。这会找到所提供日期不可用的任何房间。

(SELECT t1.room_id
FROM tbl_room t1
INNER JOIN tbl_reservation t2 ON t1.room_id = t2.room_id
INNER JOIN tbl_reservationdetails t3 ON t2.resrvdtl_id = t3.resrvdtl_id
WHERE NOT ([end date] < t3.start_date OR ([start date] > t3.end_date))

选择指定类别的所有房间。

SELECT rooms.room_id
FROM tbl_rooms rooms
INNER JOIN tbl_roomcategory cat ON rooms.room_categId = cat.room_categId
WHERE cat.room_category = [category]

这将选择指定类别但不在不可用房间内的所有房间。

AND rooms.room_id NOT IN (SELECT t1.room_id
                          FROM tbl_room t1
                          INNER JOIN tbl_reservation t2 ON t1.room_id = t2.room_id
                          INNER JOIN tbl_reservationdetails t3 ON t2.resrvdtl_id = t3.resrvdtl_id
                          WHERE NOT ([end date] < t3.start_date OR ([start date] > t3.end_date))

我无法对此进行测试,但应该是正确的。如果有任何问题,请告诉我,我会解决它。