我的任务是创建一个在线酒店预订系统。我遇到的问题是在特定日期范围内查找特定房间类别的可用房间的查询。我的数据库设计涉及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)
用户输入是日期(开始和结束),以及他想要的房间类别。我对此很新...如何在特定日期查询该类别的可用空间?????
对此的任何回应都将受到高度赞赏......谢谢
答案 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))
我无法对此进行测试,但应该是正确的。如果有任何问题,请告诉我,我会解决它。