[英]Sql for room availability
I have following table structure 我有以下表格结构
rooms table 房间表
||| room_id ||| name |||
||| 1 ||| best |||
||| 2 ||| best |||
||| 3 ||| best |||
||| 4 ||| best |||
bookings table 预订表
||| room_id ||| date_start ||| date_end |||
||| 1 ||| 2015-01-10 ||| 2015-01-15 |||
||| 2 ||| 2015-01-10 ||| 2015-01-18 |||
||| 3 ||| 2015-01-05 ||| 2015-01-10 |||
||| 4 ||| 2015-01-02 ||| 2015-01-05 |||
what i want is lets say if a user search for date_start = 2015-01-10 and date_end = 2015-01-14 我要说的是,如果用户搜索date_start = 2015-01-10和date_end = 2015-01-14
I want to show the available rooms for those days. 我想显示那几天的可用房间。
This is what i have tried so far 这是我到目前为止尝试过的
SELECT r.*
FROM rooms r
WHERE r.room_id NOT IN (
SELECT b.room_id FROM bookings b
WHERE (b.date_start <= '$data[datestart]' AND b.date_end >= '$data[dateend]'))
thank you! 谢谢!
Look at the possibilities: 看一下可能性:
x/y = your query's "find available for these days"
a/b = various records' start/end in your db
Here's every possible variant: 这是所有可能的变体:
a b
---+----+---
xy | | // no overlap
x | y | // partial overlap
x | | y // complete overlap
| xy | // complete overlap
| x | y // partial overlap
| | xy // no overlap
Once you crunch the logic down, you end up with 一旦将逻辑压缩下来,最终结果
(y < a) || (x > b) // no overlap at all
If you are considering a date range such as 01/10 and 01/14, there are three situations where a room is unavailable: 如果考虑的日期范围为01/10和01/14,则在三种情况下房间不可用:
So, for the first two you can use the BETWEEN
operator to see if dates fall in the range, and for the others use greater than or less than. 因此,对于前两个,您可以使用BETWEEN
运算符来查看日期是否在该范围内,而对于其他两个,请使用大于或小于。
What I would suggest, is write a query to get unavailable rooms: 我的建议是写一个查询以获取不可用的房间:
SELECT r.*
FROM room r
JOIN bookings b ON b.room_id = r.room_id
WHERE b.date_start BETWEEN '2015-01-10' AND '2015-01-14'
OR b.date_end BETWEEN '2015-01-10' AND '2015-01-14'
OR (b.date_start < '2015-01-10' AND b.date_end > '2015-01-14');
And then you can use NOT IN
to select from the rooms_table any rooms that aren't in this forbidden list: 然后,您可以使用NOT IN
从rooms_table中选择不在此禁止列表中的所有房间:
SELECT r.*
FROM room r
WHERE r.room_id NOT IN(
SELECT r.room_id
FROM room r
JOIN bookings b ON b.room_id = r.room_id
WHERE b.date_start BETWEEN '2015-01-10' AND '2015-01-14'
OR b.date_end BETWEEN '2015-01-10' AND '2015-01-14'
OR (b.date_start < '2015-01-10' AND b.date_end > '2015-01-14'));
If you want to avoid the subquery, you can just negate each of your conditions to get available rooms: 如果要避免子查询,可以对每个条件取反以获得可用的房间:
SELECT r.*
FROM room r
JOIN bookings b ON b.room_id = r.room_id
WHERE b.date_start NOT BETWEEN '2015-01-10' AND '2015-01-14'
AND b.date_end NOT BETWEEN '2015-01-10' AND '2015-01-14'
AND (b.date_start >= '2015-01-10' OR b.date_end <= '2015-01-14');
Here is an SQL Fiddle with all three examples. 这是带有所有三个示例的SQL Fiddle 。
SELECT rooms.room_id, rooms.name FROM rooms
INNER JOIN bookings
ON rooms.room_id =bookings.room_id
WHERE bookings.date_start >= DATE('2015-01-10') AND bookings.date_end <= DATE('2015-01-14');
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.