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,实际上确实如此。
有一个 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,实际上确实如此。