[英]Sql for room availability
我有以下表格结构
房间表
||| room_id ||| name |||
||| 1 ||| best |||
||| 2 ||| best |||
||| 3 ||| best |||
||| 4 ||| best |||
预订表
||| 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 |||
我要说的是,如果用户搜索date_start = 2015-01-10和date_end = 2015-01-14
我想显示那几天的可用房间。
这是我到目前为止尝试过的
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]'))
谢谢!
看一下可能性:
x/y = your query's "find available for these days"
a/b = various records' start/end in your db
这是所有可能的变体:
a b
---+----+---
xy | | // no overlap
x | y | // partial overlap
x | | y // complete overlap
| xy | // complete overlap
| x | y // partial overlap
| | xy // no overlap
一旦将逻辑压缩下来,最终结果
(y < a) || (x > b) // no overlap at all
如果考虑的日期范围为01/10和01/14,则在三种情况下房间不可用:
因此,对于前两个,您可以使用BETWEEN
运算符来查看日期是否在该范围内,而对于其他两个,请使用大于或小于。
我的建议是写一个查询以获取不可用的房间:
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');
然后,您可以使用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'));
如果要避免子查询,可以对每个条件取反以获得可用的房间:
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');
这是带有所有三个示例的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.