обьединение интервалов

me-to
Дата: 24.11.2009 13:47:09
Добрый день. Подскажите пожалуйста по следующей задаче:
Есть какие то настройки на оборудование с начальным интеревалом времени и конечным. Таких настроек может быть несколько.
Допустим сделали настройку одну с 10 до 15 часов, потом добавили вторую с 9 до 13, потом третью с 1 часу до 5ти. Так задача состоит в том, чтоб выяснить а сколько агрегат должен работать часов в итоге. Т.е. задача на обьединение, с включением не пересекающихся интервалов. Помогите разобраться, как ее сделать. Спасибо.
suPPLer
Дата: 24.11.2009 13:57:46
andrey_anonymous
Дата: 24.11.2009 13:59:08
Это моя любимая задачка :)
Ищите по форуму, решения приводились неоднократно.
Еще можете привести исходные данные в форме with t as (select ... from dual union all...) и ожидаемый результат.
me-to
Дата: 24.11.2009 14:14:10
Спасибо. попробую поискать. Если не получится ничего, буду опять стучаться :)
me-to
Дата: 24.11.2009 14:20:07
select trunc(sysdate)+1/24 interval_begin, trunc(sysdate)+2/24 interval_end
from dual
union all
select trunc(sysdate)+5/24 interval_begin, trunc(sysdate)+14/24 interval_end
from dual
union
select trunc(sysdate)+10/24 interval_begin, trunc(sysdate)+15/24 interval_end
from dual
union
select trunc(sysdate)+13/24 interval_begin, trunc(sysdate)+17/24 interval_end
from dual
union
select trunc(sysdate)+20/24 interval_begin, trunc(sysdate)+21/24 interval_end
from dual


ответ будет как = ( 2 часа-1 час ) + (17 часов-5часов)+(21час-20 часов)=14
andrey_anonymous
Дата: 24.11.2009 15:28:43
Вот на скорую руку, потестируйте:
SQL> with t0 as (select trunc(sysdate)+1/24 interval_begin, trunc(sysdate)+2/24 interval_end
from dual union all
select trunc(sysdate)+5/24 interval_begin, trunc(sysdate)+14/24 interval_end
from dual union all
select trunc(sysdate)+10/24 interval_begin, trunc(sysdate)+15/24 interval_end
from dual union all
select trunc(sysdate)+13/24 interval_begin, trunc(sysdate)+17/24 interval_end
from dual union all
select trunc(sysdate)+20/24 interval_begin, trunc(sysdate)+21/24 interval_end
from dual)
--------------------------< Cut here >-----------------------------------
select 24*sum(max(interval_end)-min(interval_begin)) total from (
select t.*, sum(sog) over(order by interval_begin) gr# from(
select t.*, case when interval_begin > max(interval_end)
                                      over(order by interval_begin
                                      rows between unbounded preceding and 1 preceding
                                      )
                 then 1 else 0 end sog
from t0 t) t ) t group by gr#;
 
     TOTAL
----------
        14
 
SQL> 
me-to
Дата: 24.11.2009 17:50:28
andrey_anonymous,

Спасибо.
Вроде работает. Счас будем применять на практике Ваш код ;)
me-to
Дата: 25.11.2009 18:00:16
Н емного не могу понять как вот функция окна работает rows between unbounded preceding and 1 preceding На пальцах. А то что-то не совсем понятно. Ломает немного голову.
orawish
Дата: 25.11.2009 18:08:53
me-to
Н емного не могу понять как вот функция окна работает rows between unbounded preceding and 1 preceding На пальцах. А то что-то не совсем понятно. Ломает немного голову.


between unbounded preceding and current row - понимаете?
ну а тут, почти то же, только сам - current row исключен
suPPLer
Дата: 25.11.2009 18:10:30
me-to,

брать строки от первой строки окна до предыдущей. Грубо говоря, вот:

id val sum(val) (order by id rows between unbounded preceding and 1 preceding)
1 1 null
2 1 1
3 1 2
4 2 3
5 2 5