Это похоже на проблему, которую я видел раньше. Пример запроса, который я сделал, основан на взятии каждого 15-минутного временного сегмента и анализе всех интервалов, которые его перекрывают. Попытки сделать это наоборот сбивают с толку.
Я не уверен, основываясь на комментариях, могут ли ваши реальные данные иметь повторяющиеся комбинации состояния / подсостояния на 15-минутный сегмент, и если да, то запрос ниже может потребоваться модификация для правильной агрегации.
Я заметил, что в последнем ряду вашего "Желаемого результата" у вас есть подсостояние "Занято", тогда как в наборе данных этот 35-секундный интервал говорит "ACW" , Я предположил, что это просто ошибка, и мои результаты имеют последнее значение.
Схема запроса:
Сначала мы создаем mytable2, который берет данные из вашего примера " mytable "и преобразует время начала и окончания в Oracle даты.
Затем мы создаем q1, в котором есть одна строка, в которой столбец m1 находится за час до данных и Столбец m2 находится в часе после данных.
Затем мы создаем q2, у которого есть начальная точка всех 15-минутных интервалов, в которых мы заинтересованы. Используя connect by ... rownum - это общий шаблон всякий раз, когда вам нужны последовательные числа.
Наконец, фактический запрос представляет собой четырехстороннее объединение, в котором каждая ветвь соединяет q2 и mytable2.
- Ветка # 1 - это когда интервал полностью находится внутри 15-минутного сегмента.
- Ветка # 2 - это когда 15-минутный сегмент полностью находится в интервале.
- Ветка # 3 - это где интервал начинается до и заканчивается в течение e 15-минутный сегмент.
- В филиале № 4 интервал начинается и заканчивается после 15-минутного сегмента.
with mytable2 as (
select ID, date_ as "Date",
cast(to_timestamp(date_ || ' ' || START_TIME, 'dd/mon/yy HH:MI:SS.FF AM') as date) "Start Time",
cast(to_timestamp(date_ || ' ' || END_TIME, 'dd/mon/yy HH:MI:SS.FF AM')as date) "End Time",
secs,
state,
substate
from mytable
), q1 as (
select trunc(min("Start Time"), 'hh') as m1, trunc(max("End Time")+1/24, 'hh') as m2
from mytable2
),
q2 as (
select m1 + (rownum-1)/24/4 as b1, m1 + rownum/24/4 as b2
from q1, dual
connect by rownum <= (m2-m1)*24*4
)
select "ID", "Date", "15 Int", "Secs", "State", "SubState" from (
select ID, "Date", "Start Time", to_char(b1, 'HH:MI AM') as "15 Int", secs as "Secs", state as "State", substate as "SubState" from mytable2 m
join
q2 on "Start Time" >= b1 and "End Time" <= b2
union
select ID, "Date",b1 as "Start Time", to_char(b1, 'HH:MI AM') as "15 Int", 900 , state, substate from mytable2 m
join
q2 on "Start Time" < b1 and "End Time" > b2
union
select ID, "Date",b1 as "Start Time", to_char(b1, 'HH:MI AM') as "15 Int", round(("End Time" - b1)*24*3600,0) , state, substate from mytable2 m
join
q2 on "Start Time" < b1 and ("End Time" between b1 and b2)
union
select ID, "Date","Start Time", to_char(b1, 'HH:MI AM') as "15 Int", round((b2-"Start Time")*24*3600,0), state, substate from mytable2 m
join
q2 on ("Start Time" between b1 and b2 )and "End Time" > b2
) q
order by q.ID, q."Start Time"
+-------+-----------+----------+------+----------+----------+
| ID | Date | 15 Int | Secs | State | SubState |
+-------+-----------+----------+------+----------+----------+
| 10001 | 18/MAR/20 | 09:00 AM | 170 | Ready | Ready |
| 10001 | 18/MAR/20 | 09:00 AM | 329 | NotReady | Busy |
| 10001 | 18/MAR/20 | 09:15 AM | 900 | NotReady | Busy |
| 10001 | 18/MAR/20 | 09:30 AM | 881 | NotReady | Busy |
| 10001 | 18/MAR/20 | 09:30 AM | 19 | NotReady | ACW |
| 10001 | 18/MAR/20 | 09:45 AM | 391 | NotReady | ACW |
| 10001 | 18/MAR/20 | 09:45 AM | 174 | NotReady | Busy |
| 10001 | 18/MAR/20 | 09:45 AM | 35 | NotReady | ACW |
+-------+-----------+----------+------+----------+----------+
Я использовал следующую таблицу для тестирования :
create table mytable as
select '10001' ID,'18/MAR/20' DATE_, '09:06:41.000000000 AM' START_TIME,'09:09:31.000000000 AM' END_TIME,170 secs, 'Ready' State, 'Ready' substate from dual
union all select '10001' ID,'18/MAR/20' DATE_, '09:09:31.000000000 AM' START_TIME,'09:44:41.000000000 AM' END_TIME,2110 secs, 'NotReady' State, 'Busy' substate from dual
union all select '10001' ID,'18/MAR/20' DATE_, '09:44:41.000000000 AM' START_TIME,'09:51:31.000000000 AM' END_TIME,410 secs, 'NotReady' State, 'ACW' substate from dual
union all select '10001' ID,'18/MAR/20' DATE_, '09:51:31.000000000 AM' START_TIME,'09:54:25.000000000 AM' END_TIME,174 secs, 'NotReady' State, 'Busy' substate from dual
union all select '10001' ID,'18/MAR/20' DATE_, '09:54:25.000000000 AM' START_TIME,'09:55:00.000000000 AM' END_TIME,35 secs, 'NotReady' State, 'ACW' substate from dual
+-------+-----------+-----------------------+-----------------------+------+----------+----------+
| ID | DATE_ | START_TIME | END_TIME | SECS | STATE | SUBSTATE |
+-------+-----------+-----------------------+-----------------------+------+----------+----------+
| 10001 | 18/MAR/20 | 09:06:41.000000000 AM | 09:09:31.000000000 AM | 170 | Ready | Ready |
| 10001 | 18/MAR/20 | 09:09:31.000000000 AM | 09:44:41.000000000 AM | 2110 | NotReady | Busy |
| 10001 | 18/MAR/20 | 09:44:41.000000000 AM | 09:51:31.000000000 AM | 410 | NotReady | ACW |
| 10001 | 18/MAR/20 | 09:51:31.000000000 AM | 09:54:25.000000000 AM | 174 | NotReady | Busy |
| 10001 | 18/MAR/20 | 09:54:25.000000000 AM | 09:55:00.000000000 AM | 35 | NotReady | ACW |
+-------+-----------+-----------------------+-----------------------+------+----------+----------+