#sql #oracle
#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. Каков тип данных Date, startTime и EndTime? Все ли они хранятся в виде строк? Кроме того, я предполагаю, что идентификаторы имеют смысл (например, номер комнаты, место проведения и т.д.)?
Ответ №1:
Предполагая, что все ваши входные столбцы представляют собой строки:
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;