, , , Wernfried's, , . - , , , 15- : CTE, , , selects, .
with date_time_range as (
select to_date('10/10/2013 07:00', 'DD/MM/YYYY HH24:MI') as date_start,
to_date('10/10/2013 21:15', 'DD/MM/YYYY HH24:MI') as date_end
from dual
),
time_slots as (
select level as slot_num,
dtr.date_start + (level - 1) * interval '15' minute as slot_start,
dtr.date_start + level * interval '15' minute as slot_end
from date_time_range dtr
connect by level <= (dtr.date_end - dtr.date_start) * (24 * 4)
)
select * from time_slots;
57 15- . CTE date_time_range , time_slots, , ( , JDBC ).
, , , 171 (3x57) ; - , 153 15- , .
with date_time_range as (...),
time_slots as (...),
free_slots as (
select c.classroom, ts.slot_num, ts.slot_start, ts.slot_end,
lag(ts.slot_end) over (partition by c.classroom order by ts.slot_num)
as lag_end,
lead(ts.slot_start) over (partition by c.classroom order by ts.slot_num)
as lead_start
from time_slots ts
cross join classrooms c
left join occupied_classrooms oc on oc.classroom = c.classroom
and not (oc.occupied_end <= ts.slot_start
or oc.occupied_start >= ts.slot_end)
where oc.classroom is null
)
select * from free_slots;
. ; , , :
with date_time_range as (...),
time_slots as (...),
free_slots as (...),
free_slots_extended as (
select fs.classroom, fs.slot_num,
case when fs.lag_end is null or fs.lag_end != fs.slot_start
then fs.slot_start end as slot_start,
case when fs.lead_start is null or fs.lead_start != fs.slot_end
then fs.slot_end end as slot_end
from free_slots fs
)
select * from free_slots_extended
where (fse.slot_start is not null or fse.slot_end is not null);
12 . ( where 141 153 , , ):
CLASSROOM SLOT_NUM SLOT_START SLOT_END
--------- ---------- ---------------- ----------------
A 1 2013-10-10 07:00
A 12 2013-10-10 10:00
A 19 2013-10-10 11:30
A 57 2013-10-10 21:15
B 1 2013-10-10 07:00
B 9 2013-10-10 09:15
B 16 2013-10-10 10:45
B 30 2013-10-10 14:30
B 37 2013-10-10 16:00
B 57 2013-10-10 21:15
C 1 2013-10-10 07:00
C 57 2013-10-10 21:15
, , , :
...
select distinct fse.classroom,
nvl(fse.slot_start, lag(fse.slot_start)
over (partition by fse.classroom order by fse.slot_num)) as slot_start,
nvl(fse.slot_end, lead(fse.slot_end)
over (partition by fse.classroom order by fse.slot_num)) as slot_end
from free_slots_extended fse
where (fse.slot_start is not null or fse.slot_end is not null)
:
with date_time_range as (
select to_date('10/10/2013 07:00', 'DD/MM/YYYY HH24:MI') as date_start,
to_date('10/10/2013 21:15', 'DD/MM/YYYY HH24:MI') as date_end
from dual
),
time_slots as (
select level as slot_num,
dtr.date_start + (level - 1) * interval '15' minute as slot_start,
dtr.date_start + level * interval '15' minute as slot_end
from date_time_range dtr
connect by level <= (dtr.date_end - dtr.date_start) * (24 * 4)
),
free_slots as (
select c.classroom, ts.slot_num, ts.slot_start, ts.slot_end,
lag(ts.slot_end) over (partition by c.classroom order by ts.slot_num)
as lag_end,
lead(ts.slot_start) over (partition by c.classroom order by ts.slot_num)
as lead_start
from time_slots ts
cross join classrooms c
left join occupied_classrooms oc on oc.classroom = c.classroom
and not (oc.occupied_end <= ts.slot_start
or oc.occupied_start >= ts.slot_end)
where oc.classroom is null
),
free_slots_extended as (
select fs.classroom, fs.slot_num,
case when fs.lag_end is null or fs.lag_end != fs.slot_start
then fs.slot_start end as slot_start,
case when fs.lead_start is null or fs.lead_start != fs.slot_end
then fs.slot_end end as slot_end
from free_slots fs
)
select distinct fse.classroom,
nvl(fse.slot_start, lag(fse.slot_start)
over (partition by fse.classroom order by fse.slot_num)) as slot_start,
nvl(fse.slot_end, lead(fse.slot_end)
over (partition by fse.classroom order by fse.slot_num)) as slot_end
from free_slots_extended fse
where (fse.slot_start is not null or fse.slot_end is not null)
order by 1, 2;
:
CLASSROOM SLOT_START SLOT_END
--------- ---------------- ----------------
A 2013-10-10 07:00 2013-10-10 10:00
A 2013-10-10 11:30 2013-10-10 21:15
B 2013-10-10 07:00 2013-10-10 09:15
B 2013-10-10 10:45 2013-10-10 14:30
B 2013-10-10 16:00 2013-10-10 21:15
C 2013-10-10 07:00 2013-10-10 21:15
SQL Fiddle.