我有以下表结构
房间表
||| 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]'))
谢谢你!
答案 0 :(得分:1)
看看可能性:
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
答案 1 :(得分:1)
如果您正在考虑日期范围,例如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。
答案 2 :(得分:0)
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');