按时间返回可用房间

时间:2015-01-21 17:13:37

标签: sql postgresql

有一张桌子,里面有房间的储藏室。

+----+-------+------+ | 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给我一个房间(在15:00到17:00之间检查预留)
我输入20:30 => SQL给了我没有房间(在19:30到21:30之间检查保留)

3 个答案:

答案 0 :(得分:1)

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

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;
  

我输入16:00 => SQL给我一个房间(在15:00之间检查预留   和17:00)

房间A在15:30保留,所以我认为查询应该返回B,它实际上是。

答案 1 :(得分:0)

所以,一个小时前我对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'
)

答案 2 :(得分:0)

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

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

其次,这需要独立地应用于每个房间。 我们使用窗口函数来解决。 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(...),该汇总表示如果任何当前预订产生冲突,我们将返回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    |
+====+=========+