我有一个酒店预订系统的查询,当有特定房间时,我需要查找日期。(这是一家精品酒店,人们在其中预订特定的房间,因此在获得此代码之前,他们知道他们想要的确切房间。 我要查找的结果是一个房间的详细信息,我在查询中指定了一个房间-我是不查找多个房间的信息。 )
“可用性”表模式很简单,每一行是:
room_id date_occupied - a single day that is occupied (like '2011-01-01')
因此,例如,如果某个房间在1月1日至1月5日期间被占用,则将五行添加到可用性表中,每一天占据该房间。
这是我要解决的问题:
SELECT rooms.* FROM rooms, availability WHERE rooms.id = 123 AND availability.room_id = rooms.id AND nothing between start_date and end_date is in availability.date_occupied
SELECT rooms.* FROM rooms, availability WHERE rooms.id = 123 AND availability.room_id = rooms.id AND nothing between start_date and end_date is in
availability.date_occupied
SELECT rooms.* FROM rooms, availability WHERE rooms.id = 123 AND availability.room_id = rooms.id AND start_date, start_date+1day and start_date+2days is not in availability.date_occupied
SELECT rooms.* FROM rooms, availability WHERE rooms.id = 123 AND availability.room_id = rooms.id AND start_date, start_date+1day and start_date+2days is not in
我有点想找出确切的联接。有什么建议?请注意,如果有帮助,我完全可以使用可用性表的其他模式。无论哪种方式,查询都能最有效地工作。
我认为,执行此操作的最佳方法是简单地运行查询以查看是否有房间被占用,并在不返回任何行的情况下指示可用性。
因此,对于您的第一个查询:
SELECT COUNT(id) AS occupied_days FROM availability WHERE room_id = 123 AND date_occupied BETWEEN @start_date AND @end_date;
如果occupied_days == 0可以的话。
occupied_days == 0
对于第二个查询,只需替换@end_date为DATE_ADD(@start_date, @num_days)
@end_date
DATE_ADD(@start_date, @num_days)
对于涉及联接的答案仅作一些评论:由于将搜索限制在特定范围内room_id,因此将availability表联接到room表是没有意义的,因为它没有提供必要的信息。所有这些LEFT JOIN都使查询变得复杂, 可能会降低 性能,并且没有任何用处。
room_id
availability
room
LEFT JOIN
另外,虽然您可能不愿先搜索占用率然后推断出可用性,但我猜想此查询是迄今为止查询引擎优化最快和最容易的方法,因为它基于单个列(如果建立索引),会使事情变得更快。