2011-05-04 80 views
0

我的任务是创建一个在线酒店预订系统。我遇到的问题是要找到可用客房的某个房间类别特定日期范围的查询。我的数据库设计涉及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

这看起来有点像家庭作业 - 也许先显示你的工作 - 提示你需要使用加入 – daven11 2011-05-04 10:40:04

+0

我会添加'tbl_room.room_notes',就像*'接近电梯'*(或*'...电梯'*,如果它是在另一大西洋一侧)或*'市中心的美景*'。 – 2011-05-05 15:45:11

回答

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)) 

我还没有能够测试这个,但应该是正确的。如果有任何问题,请告诉我,我会解决它。

+0

我真的不明白的部分,你拿到房号的不可用的。也许你可以看看我的问题。是否应该返回那个时间已经预订的房间? http://stackoverflow.com/questions/34053936/getting-unavailable-dates-for-renting-a-product-that-has-stocks – CularBytes 2015-12-03 16:20:23

2

我可能会扩大所请求的日期范围为相应的日期列表,然后检查从列表中的每个日期和反对保留记录的要求类别的每个房间。

这里是我的SQL Server解决方案,它采用了recursiveCTE扩大日期范围:此查询的

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 
    ...   ...   ...