Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Объединение смежных интервалов  [new]
Tram
Member

Откуда:
Сообщений: 38
Привет.
Есть таблица, в которой хранится история изменений параметров.
create table param_values 
  (param_name varchar2(30), 
  param_value varchar2(200), 
  valid_from  date, 
  valid_to    date);

insert into PARAM_VALUES (PARAM_NAME, PARAM_VALUE, VALID_FROM, VALID_TO)
values ('A', '1', to_date('01-01-2000', 'dd-mm-yyyy'), to_date('31-12-2005', 'dd-mm-yyyy'));

insert into PARAM_VALUES (PARAM_NAME, PARAM_VALUE, VALID_FROM, VALID_TO)
values ('A', '1', to_date('01-01-2006', 'dd-mm-yyyy'), to_date('31-12-2008', 'dd-mm-yyyy'));

insert into PARAM_VALUES (PARAM_NAME, PARAM_VALUE, VALID_FROM, VALID_TO)
values ('A', '1', to_date('01-01-2009', 'dd-mm-yyyy'), to_date('31-12-2010', 'dd-mm-yyyy'));

insert into PARAM_VALUES (PARAM_NAME, PARAM_VALUE, VALID_FROM, VALID_TO)
values ('A', '2', to_date('01-01-2011', 'dd-mm-yyyy'), to_date('31-12-2011', 'dd-mm-yyyy'));

insert into PARAM_VALUES (PARAM_NAME, PARAM_VALUE, VALID_FROM, VALID_TO)
values ('A', '1', to_date('01-01-2012', 'dd-mm-yyyy'), to_date('01-01-2999', 'dd-mm-yyyy'));


Скажите плз, можно ли одним запросом объединить соседние интервалы с одинаковым значением?
Т.е. сейчас
SQL> select * from param_values order by param_name, valid_from;
PARAM_NAME  PARAM_VALUE  VALID_FROM  VALID_TO
----------- ------------ ----------- -----------
A           1            01.01.2000  31.12.2005
A           1            01.01.2006  31.12.2008
A           1            01.01.2009  31.12.2010
A           2            01.01.2011  31.12.2011
A           1            01.01.2012  01.01.2999

А надо
SQL> select * from param_values order by param_name, valid_from;
PARAM_NAME  PARAM_VALUE  VALID_FROM  VALID_TO
----------- ------------ ----------- -----------
A           1            01.01.2000  31.12.2010
A           2            01.01.2011  31.12.2011
A           1            01.01.2012  01.01.2999


Одни запросом как-то можно? Oracle 11
26 авг 14, 04:20    [16491648]     Ответить | Цитировать Сообщить модератору
 Re: Объединение смежных интервалов  [new]
Elic
Member

Откуда:
Сообщений: 29990
STFF start_of_group
26 авг 14, 07:23    [16491729]     Ответить | Цитировать Сообщить модератору
 Re: Объединение смежных интервалов  [new]
Скворцов Иван
Member

Откуда:
Сообщений: 12
with a as(
select 'A' param_name, 1 param_value, '01.01.2000' valid_from, '31.12.2005' valid_to from dual union all
select 'A' param_name, 1 param_value, '01.01.2006' valid_from, '31.12.2008' valid_to from dual union all
select 'A' param_name, 1 param_value, '01.01.2009' valid_from, '31.12.2010' valid_to from dual union all
select 'A' param_name, 2 param_value, '01.01.2011' valid_from, '31.12.2011' valid_to from dual union all
select 'A' param_name, 1 param_value, '01.01.2012' valid_from, '01.01.2999' valid_to from dual)

select v.*
      ,first_value(v.valid_from)      over (partition by v.param_name,v.param_value order by v.valid_from,v.valid_to ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) begin_interval
      ,first_value(v.f2 ignore nulls) over (partition by v.param_name,v.param_value order by v.valid_from,v.valid_to ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) end_interval
from(
select v.*
       ,case when to_date(prev_to_value,'dd.mm.yyyy') + 1 = v.valid_from      then null else v.valid_from end f1 --был разрыв назад
       ,case when to_date(v.valid_to   ,'dd.mm.yyyy') + 1 = v.next_from_value then null else v.valid_to   end f2 --будет разрыв вперед
from(
select v.*
       ,lead(v.valid_from) over (partition by v.param_name,v.param_value order by v.valid_from,v.valid_to) next_from_value
       ,lag (v.valid_to)   over (partition by v.param_name,v.param_value order by v.valid_from,v.valid_to) prev_to_value
from a v)v)v
order by v.valid_from
;
26 авг 14, 11:45    [16492850]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить