从预定的时间范围中提取可用时隙

时间:2016-10-14 16:11:21

标签: sql oracle

我正在尝试创建一个视图,该视图将从调度日历表中输出所有可用时间段,并在另一个表上预订了时间段。

鉴于表格:

Table Calendar

ID    Date         StartTime    EndTime
56    18-OCT-16    10.00.00     18.00.00
62    21-OCT-16    11.00.00     20.30.00
72    27-OCT-16    09.30.00     17.00.00
72    28-OCT-16    08.40.00     18.00.00

Table ScheduledTimes

ID    Date         StartTime    EndTime
62    21-OCT-16    13.00.00     14.30.00
62    21-OCT-16    16.00.00     17.00.00
62    21-OCT-16    17.20.00     18.00.00
72    27-OCT-16    09.30.00     10.00.00
72    27-OCT-16    10.00.00     11.00.00
72    28-OCT-16    09.41.00     11.00.00
72    28-OCT-16    12.40.00     18.00.00

我正在寻找实现这一目标的方法:

ID    Date         StartTime    EndTime
56    18-OCT-16    10.00.00     18.00.00
62    21-OCT-16    11.00.00     13.00.00
62    21-OCT-16    14.30.00     16.00.00
62    21-OCT-16    17.00.00     17.20.00
62    21-OCT-16    18.00.00     20.30.00
72    27-OCT-16    11.00.00     17.00.00
72    28-OCT-16    08.40.00     09.41.00
72    28-OCT-16    11.00.00     12.40.00

ScheduledTimes的值都经过验证,确保在日历时间的时间范围内,并且彼此之间没有冲突。

1 个答案:

答案 0 :(得分:2)

假设您的输入列都是字符串:

with
     calendar ( id, dt, starttime, endtime ) as (
       select 56, '18-OCT-16', '10.00.00', '18.00.00' from dual union all
       select 62, '21-OCT-16', '11.00.00', '20.30.00' from dual union all
       select 72, '27-OCT-16', '09.30.00', '17.00.00' from dual union all
       select 72, '28-OCT-16', '08.40.00', '18.00.00' from dual
     ),
     scheduledtimes ( id, dt, starttime, endtime ) as (
       select 62, '21-OCT-16', '13.00.00', '14.30.00' from dual union all
       select 62, '21-OCT-16', '16.00.00', '17.00.00' from dual union all
       select 62, '21-OCT-16', '17.20.00', '18.00.00' from dual union all
       select 72, '27-OCT-16', '09.30.00', '10.00.00' from dual union all
       select 72, '27-OCT-16', '10.00.00', '11.00.00' from dual union all
       select 72, '28-OCT-16', '09.41.00', '11.00.00' from dual union all
       select 72, '28-OCT-16', '12.40.00', '18.00.00' from dual
     ),
     u ( id, dt, startdatetime, enddatetime ) as (
       select id, dt, to_date(dt || starttime, 'dd-MON-yyhh24.mi.ss'),
                      to_date(dt || endtime  , 'dd-MON-yyhh24.mi.ss')
         from scheduledtimes
       union all
       select id, dt, null, to_date(dt || starttime, 'dd-MON-yyhh24.mi.ss')
         from calendar
       union all
       select id, dt, to_date(dt || endtime, 'dd-MON-yyhh24.mi.ss'), null
         from calendar
     ),
     prep ( id, dt, starttime, endtime ) as (
       select id, dt, to_char(enddatetime, 'hh24:mi:ss') as starttime,
              to_char(lead(startdatetime) over (partition by id, dt 
                           order by enddatetime), 'hh24:mi:ss') as endtime
       from   u
     )
select id, dt, starttime, endtime
from   prep
where  starttime < endtime
order by id, dt, endtime;