如何在PostgreSql中的预订表中找到第一个空闲时间

And*_*rus 3 sql postgresql schedule postgresql-9.2

预订表包含预订开始日期,开始时间和持续时间.开始时间是工作时间的8:00到18:00工作时间的半小时增量.持续时间也是一天半小时的增量.

CREATE TABLE reservation (
  startdate date not null,  -- start date
  starthour numeric(4,1) not null , -- start hour 8 8.5 9 9.5  ..  16.5 17 17.5
  duration  Numeric(3,1) not null, -- duration by hours 0.5 1 1.5 .. 9 9.5 10
  primary key (startdate, starthour)
);
Run Code Online (Sandbox Code Playgroud)

如果需要,表结构可以更改.

如何在表中找到第一个免费半小时的未预约?如果表包含,则等式

startdate   starthour  duration 
14          9           1              -- ends at 9:59
14          10          1.5            -- ends at 11:29, e.q there is 30 minute gap before next
14          12          2
14          16          2.5
Run Code Online (Sandbox Code Playgroud)

结果应该是:

starthour  duration
11.5       0.5
Run Code Online (Sandbox Code Playgroud)

可能用PostgreSql 9.2窗口函数来查找其starthour大于上一行starthour + duration的第一行
如何编写返回此信息的select语句?

mys*_*mys 9

Postgres 9.2有范围类型,我建议使用它们.

create table reservation (reservation tsrange);
insert into reservation values 
('[2012-11-14 09:00:00,2012-11-14 10:00:00)'), 
('[2012-11-14 10:00:00,2012-11-14 11:30:00)'), 
('[2012-11-14 12:00:00,2012-11-14 14:00:00)'), 
('[2012-11-14 16:00:00,2012-11-14 18:30:00)');

ALTER TABLE reservation ADD EXCLUDE USING gist (reservation WITH &&);
Run Code Online (Sandbox Code Playgroud)

"EXCLUDE USING gist"创建了不允许插入重叠条目的索引.您可以使用以下查询来查找间隙(vyegorov查询的变体):

with gaps as (
  select 
    upper(reservation) as start, 
    lead(lower(reservation),1,upper(reservation)) over (ORDER BY reservation) - upper(reservation) as gap 
  from (
    select * 
    from reservation 
    union all values 
      ('[2012-11-14 00:00:00, 2012-11-14 08:00:00)'::tsrange), 
      ('[2012-11-14 18:00:00, 2012-11-15 00:00:00)'::tsrange)
  ) as x
) 
select * from gaps where gap > '0'::interval;
Run Code Online (Sandbox Code Playgroud)

'联合所有价值'掩盖了非工作时间,因此您只能在上午8点到晚上18点之间预订.

结果如下:

        start        |   gap    
---------------------+----------
 2012-11-14 08:00:00 | 01:00:00
 2012-11-14 11:30:00 | 00:30:00
 2012-11-14 14:00:00 | 02:00:00
Run Code Online (Sandbox Code Playgroud)

文档链接: - http://www.postgresql.org/docs/9.2/static/rangetypes.html "范围类型" - https://wiki.postgresql.org/images/7/73/Range-types-pgopen- 2012.pdf