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

Откуда:
Сообщений: 4
Есть некие отрезки a-b с типом 1, которые могут не пересекаться, могут частично или полностью включать друг друга.
Отрезки с типом 1 могут быть закрыты отрезком с типом 2.
Нужно в разрезе каждой даты выделить новые отрезки с учетом истории изменения длин этих отрезков. Как реализовать одним запросом?
Oracle 11.2

Исходные данные:
      TYPE DT                   A          B
---------- ----------- ---------- ----------
         1 30.11.1976        1689       1692
         1 04.11.1979        1688       1695
         1 04.11.1982      1674.5       1683
         1 04.11.1982      1686.5       1691
         1 05.11.1982      1674.5       1683
         1 05.11.1982      1686.6     1695.1
         1 27.04.2001      1673.5     1683.5
         2 12.04.2010        1690       1694
         1 01.12.2012        1692       1693
9 rows selected

+
with t1(type,dt,a,b)
 as (
      select 1, to_date('30.11.1976','dd.mm.yyyy'), 1689.0, 1692.0 from dual union all
      select 1, to_date('04.11.1979','dd.mm.yyyy'), 1688.0, 1695.0 from dual union all
      select 1, to_date('04.11.1982','dd.mm.yyyy'), 1674.5, 1683.0 from dual union all
      select 1, to_date('04.11.1982','dd.mm.yyyy'), 1686.5, 1691.0 from dual union all
      select 1, to_date('05.11.1982','dd.mm.yyyy'), 1674.5, 1683.0 from dual union all
      select 1, to_date('05.11.1982','dd.mm.yyyy'), 1686.6, 1695.1 from dual union all
      select 1, to_date('27.04.2001','dd.mm.yyyy'), 1673.5, 1683.5 from dual union all
      select 2, to_date('12.04.2010','dd.mm.yyyy'), 1690.0, 1694.0 from dual union all
      select 1, to_date('01.12.2012','dd.mm.yyyy'), 1692.0, 1693.0 from dual
    )
select * from t1 order by 2,3;


Нужно получить:
DT                   A          B
----------- ---------- ----------
30.11.1976        1689       1692
04.11.1979        1688       1689
04.11.1979        1689       1692
04.11.1979        1692       1695
04.11.1982      1674.5       1683
04.11.1982      1686.5       1688
04.11.1982        1688       1691
04.11.1982        1691       1692
04.11.1982        1692       1695
05.11.1982      1674.5       1683
05.11.1982      1686.5     1686.6
05.11.1982      1686.6       1695
05.11.1982        1695     1695.1
27.04.2001      1673.5     1674.5
27.04.2001      1674.5       1683
27.04.2001        1683     1683.5
27.04.2001      1686.5     1686.6
27.04.2001      1686.6       1695
27.04.2001        1695     1695.1
12.04.2010      1673.5     1674.5
12.04.2010      1674.5       1683
12.04.2010        1683     1683.5
12.04.2010      1686.5     1686.6
12.04.2010      1686.6       1690
12.04.2010        1690       1694
12.04.2010        1694       1695
12.04.2010        1695     1695.1
01.12.2012      1673.5     1674.5
01.12.2012      1674.5       1683
01.12.2012        1683     1683.5
01.12.2012      1686.5     1686.6
01.12.2012      1686.6       1690
01.12.2012        1690       1692
01.12.2012        1692       1693
01.12.2012        1693       1694
01.12.2012        1694       1695
01.12.2012        1695     1695.1
37 rows selected

+
with t2(dt,a,b)
        as (
            select to_date('30.11.1976','dd.mm.yyyy'), 1689.0 , 1692.0 from dual union all
            select to_date('04.11.1979','dd.mm.yyyy'), 1688.0 , 1689.0 from dual union all
            select to_date('04.11.1979','dd.mm.yyyy'), 1689.0 , 1692.0 from dual union all
            select to_date('04.11.1979','dd.mm.yyyy'), 1692.0 , 1695.0 from dual union all
            select to_date('04.11.1982','dd.mm.yyyy'), 1674.5 , 1683.0 from dual union all
            select to_date('04.11.1982','dd.mm.yyyy'), 1686.5 , 1688.0 from dual union all
            select to_date('04.11.1982','dd.mm.yyyy'), 1688.0 , 1691.0 from dual union all
            select to_date('04.11.1982','dd.mm.yyyy'), 1691.0 , 1692.0 from dual union all
            select to_date('04.11.1982','dd.mm.yyyy'), 1692.0 , 1695.0 from dual union all
            select to_date('05.11.1982','dd.mm.yyyy'), 1674.5 , 1683.0 from dual union all
            select to_date('05.11.1982','dd.mm.yyyy'), 1686.5 , 1686.6 from dual union all
            select to_date('05.11.1982','dd.mm.yyyy'), 1686.6 , 1695.0 from dual union all
            select to_date('05.11.1982','dd.mm.yyyy'), 1695.0 , 1695.1 from dual union all
            select to_date('27.04.2001','dd.mm.yyyy'), 1673.5 , 1674.5 from dual union all
            select to_date('27.04.2001','dd.mm.yyyy'), 1674.5 , 1683.0 from dual union all
            select to_date('27.04.2001','dd.mm.yyyy'), 1683.0 , 1683.5 from dual union all
            select to_date('27.04.2001','dd.mm.yyyy'), 1686.5 , 1686.6 from dual union all
            select to_date('27.04.2001','dd.mm.yyyy'), 1686.6 , 1695.0 from dual union all
            select to_date('27.04.2001','dd.mm.yyyy'), 1695.0 , 1695.1 from dual union all
            select to_date('12.04.2010','dd.mm.yyyy'), 1673.5 , 1674.5 from dual union all
            select to_date('12.04.2010','dd.mm.yyyy'), 1674.5 , 1683.0 from dual union all
            select to_date('12.04.2010','dd.mm.yyyy'), 1683.0 , 1683.5 from dual union all
            select to_date('12.04.2010','dd.mm.yyyy'), 1686.5 , 1686.6 from dual union all
            select to_date('12.04.2010','dd.mm.yyyy'), 1686.6 , 1690.0 from dual union all
            select to_date('12.04.2010','dd.mm.yyyy'), 1690.0 , 1694.0 from dual union all
            select to_date('12.04.2010','dd.mm.yyyy'), 1694.0 , 1695.0 from dual union all
            select to_date('12.04.2010','dd.mm.yyyy'), 1695.0 , 1695.1 from dual union all
            select to_date('01.12.2012','dd.mm.yyyy'), 1673.5 , 1674.5 from dual union all
            select to_date('01.12.2012','dd.mm.yyyy'), 1674.5 , 1683.0 from dual union all
            select to_date('01.12.2012','dd.mm.yyyy'), 1683.0 , 1683.5 from dual union all
            select to_date('01.12.2012','dd.mm.yyyy'), 1686.5 , 1686.6 from dual union all
            select to_date('01.12.2012','dd.mm.yyyy'), 1686.6 , 1690.0 from dual union all
            select to_date('01.12.2012','dd.mm.yyyy'), 1690.0 , 1692.0 from dual union all
            select to_date('01.12.2012','dd.mm.yyyy'), 1692.0 , 1693.0 from dual union all
            select to_date('01.12.2012','dd.mm.yyyy'), 1693.0 , 1694.0 from dual union all
            select to_date('01.12.2012','dd.mm.yyyy'), 1694.0 , 1695.0 from dual union all
            select to_date('01.12.2012','dd.mm.yyyy'), 1695.0 , 1695.1 from dual
           )
select * from t2 order by 1,2;
10 апр 19, 15:09    [21858404]     Ответить | Цитировать Сообщить модератору
 Re: Как решить на sql  [new]
Stax
Member

Откуда: Ukraine,Lviv
Сообщений: 1869
tira mi su,

"обеденить" пересекающиеся интервальчики (Добрый Ех с рисунками показывал как)

и допилить с учетом загадочного "Отрезки с типом 1 могут быть закрыты отрезком с типом 2."

....
stax
10 апр 19, 15:27    [21858432]     Ответить | Цитировать Сообщить модератору
 Re: Как решить на sql  [new]
tira mi su
Member

Откуда:
Сообщений: 4
Забыл указать столбец типа результата...
Нужно получить:
DT                   A          B TYPE2
----------- ---------- ---------- -----------
30.11.1976        1689       1692 первичный
04.11.1979        1688       1689 добавлен
04.11.1979        1689       1692 пересечение
04.11.1979        1692       1695 добавлен
04.11.1982      1674.5       1683 добавлен
04.11.1982      1686.5       1688 добавлен
04.11.1982        1688       1691 пересечение
04.11.1982        1691       1692 пересечение
04.11.1982        1692       1695 добавлен
05.11.1982      1674.5       1683 пересечение
05.11.1982      1686.5     1686.6 добавлен
05.11.1982      1686.6       1695 пересечение
05.11.1982        1695     1695.1 добавлен
27.04.2001      1673.5     1674.5 добавлен
27.04.2001      1674.5       1683 пересечение
27.04.2001        1683     1683.5 добавлен
27.04.2001      1686.5     1686.6 добавлен
27.04.2001      1686.6       1695 пересечение
27.04.2001        1695     1695.1 добавлен
12.04.2010      1673.5     1674.5 добавлен
12.04.2010      1674.5       1683 пересечение
12.04.2010        1683     1683.5 добавлен
12.04.2010      1686.5     1686.6 добавлен
12.04.2010      1686.6       1690 пересечение
12.04.2010        1690       1694 закрыт
12.04.2010        1694       1695 пересечение
12.04.2010        1695     1695.1 добавлен
01.12.2012      1673.5     1674.5 добавлен
01.12.2012      1674.5       1683 пересечение
01.12.2012        1683     1683.5 добавлен
01.12.2012      1686.5     1686.6 добавлен
01.12.2012      1686.6       1690 пересечение
01.12.2012        1690       1692 закрыт
01.12.2012        1692       1693 вторичный
01.12.2012        1693       1694 закрыт
01.12.2012        1694       1695 пересечение
01.12.2012        1695     1695.1 добавлен
37 rows selected

+
with t2(dt,a,b,type2)
        as (
            select to_date('30.11.1976','dd.mm.yyyy'), 1689.0 , 1692.0,'первичный' from dual union all
            select to_date('04.11.1979','dd.mm.yyyy'), 1688.0 , 1689.0,'добавлен' from dual union all
            select to_date('04.11.1979','dd.mm.yyyy'), 1689.0 , 1692.0,'пересечение' from dual union all
            select to_date('04.11.1979','dd.mm.yyyy'), 1692.0 , 1695.0,'добавлен' from dual union all
            select to_date('04.11.1982','dd.mm.yyyy'), 1674.5 , 1683.0,'добавлен' from dual union all
            select to_date('04.11.1982','dd.mm.yyyy'), 1686.5 , 1688.0,'добавлен' from dual union all
            select to_date('04.11.1982','dd.mm.yyyy'), 1688.0 , 1691.0,'пересечение' from dual union all
            select to_date('04.11.1982','dd.mm.yyyy'), 1691.0 , 1692.0,'пересечение' from dual union all
            select to_date('04.11.1982','dd.mm.yyyy'), 1692.0 , 1695.0,'добавлен' from dual union all
            select to_date('05.11.1982','dd.mm.yyyy'), 1674.5 , 1683.0,'пересечение' from dual union all
            select to_date('05.11.1982','dd.mm.yyyy'), 1686.5 , 1686.6,'добавлен' from dual union all
            select to_date('05.11.1982','dd.mm.yyyy'), 1686.6 , 1695.0,'пересечение' from dual union all
            select to_date('05.11.1982','dd.mm.yyyy'), 1695.0 , 1695.1,'добавлен' from dual union all
            select to_date('27.04.2001','dd.mm.yyyy'), 1673.5 , 1674.5,'добавлен' from dual union all
            select to_date('27.04.2001','dd.mm.yyyy'), 1674.5 , 1683.0,'пересечение' from dual union all
            select to_date('27.04.2001','dd.mm.yyyy'), 1683.0 , 1683.5,'добавлен' from dual union all
            select to_date('27.04.2001','dd.mm.yyyy'), 1686.5 , 1686.6,'добавлен' from dual union all
            select to_date('27.04.2001','dd.mm.yyyy'), 1686.6 , 1695.0,'пересечение' from dual union all
            select to_date('27.04.2001','dd.mm.yyyy'), 1695.0 , 1695.1,'добавлен' from dual union all
            select to_date('12.04.2010','dd.mm.yyyy'), 1673.5 , 1674.5,'добавлен' from dual union all
            select to_date('12.04.2010','dd.mm.yyyy'), 1674.5 , 1683.0,'пересечение' from dual union all
            select to_date('12.04.2010','dd.mm.yyyy'), 1683.0 , 1683.5,'добавлен' from dual union all
            select to_date('12.04.2010','dd.mm.yyyy'), 1686.5 , 1686.6,'добавлен' from dual union all
            select to_date('12.04.2010','dd.mm.yyyy'), 1686.6 , 1690.0,'пересечение' from dual union all
            select to_date('12.04.2010','dd.mm.yyyy'), 1690.0 , 1694.0,'закрыт' from dual union all
            select to_date('12.04.2010','dd.mm.yyyy'), 1694.0 , 1695.0,'пересечение' from dual union all
            select to_date('12.04.2010','dd.mm.yyyy'), 1695.0 , 1695.1,'добавлен' from dual union all
            select to_date('01.12.2012','dd.mm.yyyy'), 1673.5 , 1674.5,'добавлен' from dual union all
            select to_date('01.12.2012','dd.mm.yyyy'), 1674.5 , 1683.0,'пересечение' from dual union all
            select to_date('01.12.2012','dd.mm.yyyy'), 1683.0 , 1683.5,'добавлен' from dual union all
            select to_date('01.12.2012','dd.mm.yyyy'), 1686.5 , 1686.6,'добавлен' from dual union all
            select to_date('01.12.2012','dd.mm.yyyy'), 1686.6 , 1690.0,'пересечение' from dual union all
            select to_date('01.12.2012','dd.mm.yyyy'), 1690.0 , 1692.0,'закрыт' from dual union all
            select to_date('01.12.2012','dd.mm.yyyy'), 1692.0 , 1693.0,'вторичный' from dual union all
            select to_date('01.12.2012','dd.mm.yyyy'), 1693.0 , 1694.0,'закрыт' from dual union all
            select to_date('01.12.2012','dd.mm.yyyy'), 1694.0 , 1695.0,'пересечение' from dual union all
            select to_date('01.12.2012','dd.mm.yyyy'), 1695.0 , 1695.1,'добавлен' from dual
           )
select * from t2 order by 1,2;
10 апр 19, 15:30    [21858436]     Ответить | Цитировать Сообщить модератору
 Re: Как решить на sql  [new]
andreymx
Member

Откуда: Запорожье
Сообщений: 51735
Слава богу.... А то я думал, что с ума сошёл
10 апр 19, 15:35    [21858444]     Ответить | Цитировать Сообщить модератору
 Re: Как решить на sql  [new]
Stax
Member

Откуда: Ukraine,Lviv
Сообщений: 1869
tira mi su,

ой
приврал, Вам не надо обьеденять интервальчики, а наоборот


.....
stax
10 апр 19, 15:36    [21858447]     Ответить | Цитировать Сообщить модератору
 Re: Как решить на sql  [new]
andreymx
Member

Откуда: Запорожье
Сообщений: 51735
Хотя по колонке с описанием вопросы остались
10 апр 19, 15:39    [21858451]     Ответить | Цитировать Сообщить модератору
 Re: Как решить на sql  [new]
andreymx
Member

Откуда: Запорожье
Сообщений: 51735
а зачем это делать одним запросом?
10 апр 19, 16:46    [21858602]     Ответить | Цитировать Сообщить модератору
 Re: Как решить на sql  [new]
tira mi su
Member

Откуда:
Сообщений: 4
andreymx
а зачем это делать одним запросом?

Академический интерес. Реально ли и если реально, то посмотреть решение. Сам не осилил.
10 апр 19, 17:04    [21858627]     Ответить | Цитировать Сообщить модератору
 Re: Как решить на sql  [new]
Stax
Member

Откуда: Ukraine,Lviv
Сообщений: 1869
tira mi su
andreymx
а зачем это делать одним запросом?

Академический интерес. Реально ли и если реально, то посмотреть решение. Сам не осилил.


попробовать рекурсивно (относительно дат) вызывать алгоритм Доброго Эха, или другой обьеденения интервалов
будет пауза попытаюсь

....
stax
10 апр 19, 17:16    [21858638]     Ответить | Цитировать Сообщить модератору
 Re: Как решить на sql  [new]
andreymx
Member

Откуда: Запорожье
Сообщений: 51735
Stax
tira mi su
пропущено...

Академический интерес. Реально ли и если реально, то посмотреть решение. Сам не осилил.


попробовать рекурсивно (относительно дат) вызывать алгоритм Доброго Эха, или другой обьеденения интервалов
будет пауза попытаюсь

....
stax
и разъединения :)
тип 2 не забываем
10 апр 19, 18:02    [21858660]     Ответить | Цитировать Сообщить модератору
 Re: Как решить на sql  [new]
andreymx
Member

Откуда: Запорожье
Сообщений: 51735
А если добавлены сразу два пересекающихся отрезка, как отображать
10 апр 19, 18:20    [21858672]     Ответить | Цитировать Сообщить модератору
 Re: Как решить на sql  [new]
Щукина Анна
Member

Откуда:
Сообщений: 1403
tira mi su,

Ознакомьтесь. Может подчерпнете для себя идею реализации...
10 апр 19, 20:57    [21858796]     Ответить | Цитировать Сообщить модератору
 Re: Как решить на sql  [new]
xtender
Member

Откуда: Мск
Сообщений: 5146
tira mi su,

что-то хреново с постановкой задачи и примером.
tira mi su
Нужно получить:
DT                   A          B
----------- ---------- ----------
30.11.1976        1689       1692
04.11.1979        1688       1689
04.11.1979        1689       1692
04.11.1979        1692       1695
04.11.1982      1674.5       1683
04.11.1982      1686.5       1688
04.11.1982        1688       1691 -- почему сразу 1691? куда 1689 потеряли?
04.11.1982        1691       1692
04.11.1982        1692       1695
05.11.1982      1674.5       1683
05.11.1982      1686.5     1686.6
05.11.1982      1686.6       1695 -- почему сразу 1695? а где 1688,1689,1691,1692?
05.11.1982        1695     1695.1
27.04.2001      1673.5     1674.5
27.04.2001      1674.5       1683
27.04.2001        1683     1683.5
27.04.2001      1686.5     1686.6
27.04.2001      1686.6       1695 -- почему сразу 1695? а где 1688,1689,1691,1692?
27.04.2001        1695     1695.1
12.04.2010      1673.5     1674.5
12.04.2010      1674.5       1683
12.04.2010        1683     1683.5
12.04.2010      1686.5     1686.6
12.04.2010      1686.6       1690 - почему 1690? где 1688,1689?
12.04.2010        1690       1694
12.04.2010        1694       1695
12.04.2010        1695     1695.1
01.12.2012      1673.5     1674.5
01.12.2012      1674.5       1683
01.12.2012        1683     1683.5
01.12.2012      1686.5     1686.6
01.12.2012      1686.6       1690 - почему 1690? где 1688,1689?
01.12.2012        1690       1692
01.12.2012        1692       1693
01.12.2012        1693       1694
01.12.2012        1694       1695
01.12.2012        1695     1695.1
37 rows selected

Посмотри на картинку и объясни как, что и откуда должно появляться

К сообщению приложен файл. Размер - 10Kb
11 апр 19, 03:18    [21858864]     Ответить | Цитировать Сообщить модератору
 Re: Как решить на sql  [new]
xtender
Member

Откуда: Мск
Сообщений: 5146
tira mi su,

сравни с результатом этого запроса:
+
with t1(type,dt,a,b)
 as (
      select 1, to_date('30.11.1976','dd.mm.yyyy'), 1689.0, 1692.0 from dual union all
      select 1, to_date('04.11.1979','dd.mm.yyyy'), 1688.0, 1695.0 from dual union all
      select 1, to_date('04.11.1982','dd.mm.yyyy'), 1674.5, 1683.0 from dual union all
      select 1, to_date('04.11.1982','dd.mm.yyyy'), 1686.5, 1691.0 from dual union all
      select 1, to_date('05.11.1982','dd.mm.yyyy'), 1674.5, 1683.0 from dual union all
      select 1, to_date('05.11.1982','dd.mm.yyyy'), 1686.6, 1695.1 from dual union all
      select 1, to_date('27.04.2001','dd.mm.yyyy'), 1673.5, 1683.5 from dual union all
      select 2, to_date('12.04.2010','dd.mm.yyyy'), 1690.0, 1694.0 from dual union all
      select 1, to_date('01.12.2012','dd.mm.yyyy'), 1692.0, 1693.0 from dual
    )
,points as (
   select distinct * 
   from t1 
   unpivot (
     p 
     for marker in (a,b)
   )
)
,dates as (
   select distinct dt as dt2 from t1
)
,all_dates_points as (
   select distinct type,dt2,marker,p
   from points
       ,dates
   where dt2>=points.dt
)
,mark_endpoints as(
   select adp.*
         ,case when marker='A' 
                 or exists(select null 
                           from t1 
                           where t1.dt<=adp.dt2 
                           and adp.p >= t1.a 
                           and adp.p < t1.b) 
               then 'is not end' 
               else 'end' 
          end flag
   from all_dates_points adp
)
,skip_endpoints as(
select type,dt2,marker,p,flag,p as p_start,lead(p)over(partition by dt2 order by p) as p_end
from mark_endpoints e
where not exists(select 1 from t1 where t1.dt=e.dt2 and t1.type=2 and p>t1.a and p <t1.b)
)
select type, dt2
       --,marker,p, flag
       ,p_start,p_end
from skip_endpoints 
where flag!='end'
order by dt2,p;

TYPEDT2P_STARTP_END
11976-11-3016891692
11979-11-0416881689
11979-11-0416891692
11979-11-0416921695
11982-11-041674.51683
11982-11-041686.51688
11982-11-0416881689
11982-11-0416891691
11982-11-0416911692
11982-11-0416921695
11982-11-051674.51683
11982-11-051686.51686.6
11982-11-051686.61688
11982-11-0516881689
11982-11-0516891691
11982-11-0516911692
11982-11-0516921695
11982-11-0516951695.1
12001-04-271673.51674.5
12001-04-271674.51683
12001-04-2716831683.5
12001-04-271686.51686.6
12001-04-271686.61688
12001-04-2716881689
12001-04-2716891691
12001-04-2716911692
12001-04-2716921695
12001-04-2716951695.1
12010-04-121673.51674.5
12010-04-121674.51683
12010-04-1216831683.5
12010-04-121686.51686.6
12010-04-121686.61688
12010-04-1216881689
12010-04-1216891690
22010-04-1216901694
22010-04-1216941695
12010-04-1216951695.1
12012-12-011673.51674.5
12012-12-011674.51683
12012-12-0116831683.5
12012-12-011686.51686.6
12012-12-011686.61688
12012-12-0116881689
12012-12-0116891690
22012-12-0116901691
12012-12-0116911692
12012-12-0116921692
12012-12-0116921693
12012-12-0116931694
22012-12-0116941695
12012-12-0116951695.1
11 апр 19, 03:20    [21858865]     Ответить | Цитировать Сообщить модератору
 Re: Как решить на sql  [new]
Stax
Member

Откуда: Ukraine,Lviv
Сообщений: 1869
xtender
tira mi su,
что-то хреново с постановкой задачи и примером.

Посмотри на картинку и объясни как, что и откуда должно появляться


спасибо за картинку, так проще

я понял задачу так
тип 1
0) обьеденяем интервалы первого дня (в примере один интервл то пропускаем)
1) идем по днях (начинаем со второго 04.11.1979 )
2) обьеденяем интервалы текущего дня с результатом расчета предыдущего (все итервалы с начала по текущий)
3) следующий день и п2

все что попадает в интервал тип2 удаляем (с учетом пересечений)

если ето так как я описал можно попробовать использовать алгоритм типа ДоброгоЭха добавив "partition"

если отрезки не обеденять, то их к-во должно токо расти, а ж нет (напр 05.11.1982)

зы
имхо для теста проще пример делать на небольших целых числах (напр с 1 по то 100)



.....
stax
11 апр 19, 09:23    [21858953]     Ответить | Цитировать Сообщить модератору
 Re: Как решить на sql  [new]
andreymx
Member

Откуда: Запорожье
Сообщений: 51735
что-то в таком виде
Stax
имхо для теста проще пример делать на небольших целых числах (напр с 1 по то 100)
WITH T AS
(
SELECT 1 TYPE, DATE '2001-1-1' dt, 4 a, 7 b FROM dual UNION ALL
SELECT 1 TYPE, DATE '2001-1-2' dt, 6 a, 8 b FROM dual UNION ALL
SELECT 1 TYPE, DATE '2001-1-3' dt, 1 a, 2 b FROM dual UNION ALL
SELECT 1 TYPE, DATE '2001-1-3' dt, 3 a, 5 b FROM dual 
)
SELECT t.*,
       LPAD('-', a, '-')||
       LPAD('#', b-a, '#')||
       LPAD('-', MAX(b) OVER() - b, '-')
  from t
TYPEDTABVIS
101/01/200147----###-
102/01/200168------##
103/01/200112-#------
103/01/200135---##---
TYPE		vis
1 01/01/2001 4 7 ----###-
1 02/01/2001 6 8 ------##
1 03/01/2001 1 2 -#------
1 03/01/2001 3 5 ---##---
11 апр 19, 09:39    [21858963]     Ответить | Цитировать Сообщить модератору
 Re: Как решить на sql  [new]
Stax
Member

Откуда: Ukraine,Lviv
Сообщений: 1869
andreymx
что-то в таком виде

я б для теста даж MAX(b) over() заменил на константу

.....
stax
11 апр 19, 09:49    [21858969]     Ответить | Цитировать Сообщить модератору
 Re: Как решить на sql  [new]
Stax
Member

Откуда: Ukraine,Lviv
Сообщений: 1869
andreymx
что-то в таком виде

a-b включно
чутку подправил
SQL> ed
Wrote file afiedt.buf

  1  WITH T AS
  2  (
  3  SELECT 1 TYPE, DATE '2001-1-1' dt, 4 a, 7 b FROM dual UNION ALL
  4  SELECT 1 TYPE, DATE '2001-1-2' dt, 6 a, 8 b FROM dual UNION ALL
  5  SELECT 1 TYPE, DATE '2001-1-3' dt, 1 a, 2 b FROM dual UNION ALL
  6  SELECT 1 TYPE, DATE '2001-1-3' dt, 3 a, 5 b FROM dual
  7  )
  8  SELECT t.*,
  9         LPAD('-', a-1, '-')||
 10         LPAD('#', b-a+1, '#')||
 11         LPAD('-', MAX(b) OVER() - b, '-') d
 12*   from t
SQL> /

      TYPE DT                A          B D
---------- -------- ---------- ---------- ----------
         1 01.01.01          4          7 ---####-
         1 02.01.01          6          8 -----###
         1 03.01.01          1          2 ##------
         1 03.01.01          3          5 --###---


.....
stax
11 апр 19, 10:05    [21858981]     Ответить | Цитировать Сообщить модератору
 Re: Как решить на sql  [new]
xtender
Member

Откуда: Мск
Сообщений: 5146
Stax
я понял задачу так
тип 1
0) обьеденяем интервалы первого дня (в примере один интервл то пропускаем)
1) идем по днях (начинаем со второго 04.11.1979 )
2) обьеденяем интервалы текущего дня с результатом расчета предыдущего (все итервалы с начала по текущий)
3) следующий день и п2
из исходного примера видно, что сворачивать/объединять интервалы не нужно. Наоборот, их надо разбить


Stax
если ето так как я описал можно попробовать использовать алгоритм типа ДоброгоЭха добавив "partition"
про что речь? если про разложение интервала в список точек с помощью генераторов с последующей сверткой, то это не пойдет как из-за нецелых чисел, так и в целом из-за отсутствия необходимости сворачивания интервалов.

Исходную задачу можно еще решить геморройным рекурсивным with, но на большом кол-ве строк это умрет
11 апр 19, 13:08    [21859312]     Ответить | Цитировать Сообщить модератору
 Re: Как решить на sql  [new]
andreymx
Member

Откуда: Запорожье
Сообщений: 51735
xtender
Исходную задачу можно еще решить геморройным рекурсивным with, но на большом кол-ве строк это умрет
ТС вроде говорил об академическом интересе
11 апр 19, 13:47    [21859400]     Ответить | Цитировать Сообщить модератору
 Re: Как решить на sql  [new]
Stax
Member

Откуда: Ukraine,Lviv
Сообщений: 1869
xtender
про что речь? если про разложение интервала в список точек с помощью генераторов с последующей сверткой

нет не об разложении

просто я не понимаю что надо сделать

если "их надо разбить", то к-во должно увеличиватся (как в Вашем решении),
но для 05.11.1982 их всего 4

.....
stax
11 апр 19, 14:23    [21859489]     Ответить | Цитировать Сообщить модератору
 Re: Как решить на sql  [new]
xtender
Member

Откуда: Мск
Сообщений: 5146
Stax
если "их надо разбить", то к-во должно увеличиватся (как в Вашем решении),
но для 05.11.1982 их всего 4
за 05.11.1982 было 2, а стало 4 - разве это не увеличение? другое дело, что по постановке задаче и примеру с другими строками(например, за 04.11.1979), должно быть еще больше, но, видимо, "потеряли"... Я же выше уже спрашивал:
DT                   A          B
----------- ---------- ----------
30.11.1976        1689       1692
04.11.1979        1688       1689
04.11.1979        1689       1692
04.11.1979        1692       1695
04.11.1982      1674.5       1683
04.11.1982      1686.5       1688
04.11.1982        1688       1691 -- почему сразу 1691? куда 1689 потеряли?
04.11.1982        1691       1692
04.11.1982        1692       1695
05.11.1982      1674.5       1683
05.11.1982      1686.5     1686.6
05.11.1982      1686.6       1695 -- почему сразу 1695? а где 1688,1689,1691,1692?
05.11.1982        1695     1695.1
27.04.2001      1673.5     1674.5
27.04.2001      1674.5       1683
27.04.2001        1683     1683.5
27.04.2001      1686.5     1686.6
27.04.2001      1686.6       1695 -- почему сразу 1695? а где 1688,1689,1691,1692?
27.04.2001        1695     1695.1
12.04.2010      1673.5     1674.5
12.04.2010      1674.5       1683
12.04.2010        1683     1683.5
12.04.2010      1686.5     1686.6
12.04.2010      1686.6       1690 - почему 1690? где 1688,1689?
12.04.2010        1690       1694
12.04.2010        1694       1695
12.04.2010        1695     1695.1
01.12.2012      1673.5     1674.5
01.12.2012      1674.5       1683
01.12.2012        1683     1683.5
01.12.2012      1686.5     1686.6
01.12.2012      1686.6       1690 - почему 1690? где 1688,1689?
01.12.2012        1690       1692
01.12.2012        1692       1693
01.12.2012        1693       1694
01.12.2012        1694       1695
01.12.2012        1695     1695.1
37 rows selected
11 апр 19, 20:54    [21859917]     Ответить | Цитировать Сообщить модератору
 Re: Как решить на sql  [new]
tira mi su
Member

Откуда:
Сообщений: 4
Конечно ваши замечания по предоставленному мной результату верные. У каждого отрезка есть свои атрибуты, которые дополнительно вычисляются у результирующих отрезков, поэтому замечания "04.11.1982 1688 1691 -- почему сразу 1691? куда 1689 потеряли?" верные. Например, один из дополнительных атрибутов(кол-во точек) нового отрезка должен вычисляться как максимальное значение за историю жизни этого кусочка от начала жизни до текущей строки. Смежные отрезки с одинаковыми атрибутами, в конечном итоге нужно будет соединить. Также нужно учитывать интервалы с типом "закрыт". После появления вторичного отрезка начинается занового его жить, но только в переделе интервала закрыт. Т.е. он может быть добавлен, пересечен и т.д. до следующего частичного или полного закрытия. Если вторичный отрезок больше закрытого, то учитывается история с самого начала.

Задачи три: получить новые отрезки, определить тип отрезков и рассчитать дополнительные атрибуты.

Прошу прощение, за то что выпал из топика. Был занят неотложными делами.
Постараюсь на выходных более наглядно сформулировать постановку с картинками и нормальными данными. Спасибо за понимание.
12 апр 19, 10:23    [21860223]     Ответить | Цитировать Сообщить модератору
 Re: Как решить на sql  [new]
Elic
Member

Откуда: 1984. Выбраковка финно-угром продолжается. КЯЗ
Сообщений: 29041
tira mi su
Прошу прощение, за то что выпал из топика. Был занят неотложными делами.
Да ладно, некоторые готовы чуть ли не платить зарплату, лишь бы их закидывали неправильно сформулированными задачами.
+
Интервалы с учетом приоритета на SQL.
12 апр 19, 10:39    [21860239]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить