return 个可用房间(按时间)

return available rooms by time

有一个 table 包含房间预订。

+----+-------+------+ | id | time | room | +----+-------+------+ | 1 | 12:00 | A | | 2 | 13:30 | A | | 3 | 15:30 | A | | 4 | 20:00 | A | | 5 | 10:00 | B | | 6 | 21:00 | B | +----+-------+------+

我想获得按时间 +- 1 小时(间隔 +-1 小时)容纳的房间。
例如,如果我说 19:00,我必须检查没有18:00 到 20:00 之间的预订。

一些例子:
我输入 18:30 => SQL 给我 A 和 B 房间 (检查 17:30 和 19:30 之间的预订)
我输入 16:00 => SQL 给我 A 房间 (检查 15:00 和 17:00 之间的预订)
我输入 20:30 => SQL 没有空间给我 (检查 19:30 和 21:30 之间的储备)

所以,一个小时前我对 postgresql 一无所知,但这是我拼凑的概念证明。可能有更有效的方法:

create table foo
(
  id serial,
  time timestamp,
  room varchar(1)
);

insert into foo (time, room) values 
         ( '2015-01-21 10:00:00', 'B')
        ,( '2015-01-21 12:00:00', 'A')
        ,( '2015-01-21 13:30:00', 'A')
        ,( '2015-01-21 15:30:00', 'A')
        ,( '2015-01-21 20:00:00', 'A')
        ,( '2015-01-21 21:00:00', 'B'); 


select distinct room from foo where room not in
(
    select distinct room from foo
    where time between
    '2015-01-21 16:00:00'::timestamp - interval '1 hour' and
    '2015-01-21 16:00:00'::timestamp + interval '1 hour'
)

所以这有几个部分。 首先,任何一方在所需时间的一小时内进行的任何预订都会使房间不合格。 我们可以通过以下方式解决:

time + interval '1 hour' > @param AND time - interval '1 hour' < @param

其次,这需要独立应用于每个房间。 我们使用 window 函数解决了这个问题。 http://www.postgresql.org/docs/9.1/static/tutorial-window.html

最终结果将如下所示:

SELECT distinct room, NOT bool_or(time + interval '1 hour' > @param AND time - interval '1 hour' < @param) OVER (PARTITION BY room) as available FROM reserv;

请注意,我们正在应用聚合 NOT bool_or(...),这表示如果当前任何预订产生冲突,我们将 return false。 那么Over (PARTITION BY room)保证我们只查找单个房间范围内的冲突

示例:

SELECT distinct room, NOT bool_or(time + interval '1 hour' > '2015-01-21 16:00' AND time - interval '1 hour' < '2015-01-21 16:00') OVER (PARTITION BY room) as available FROM reserv;

将产生:

+====+=========+
|room|available|
+====+=========+
|  A |    F    |
|  B |    T    |
+====+=========+

找到预订的房间相对容易,而且您想要所有其他房间,这样就可以了:

select distinct room from res
except
select distinct room 
from res 
where time between cast('2015-01-01 16:00' as timestamp without time zone) - interval '1 hour' and cast('2015-01-01 16:00' as timestamp without time zone) + interval '1 hour'
order by 1;

I enter 16:00 => SQL give me back A room (check reservs between 15:00 and 17:00)

房间 A 在 15:30 预订,所以我认为查询应该是 return B,实际上确实如此。