powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Как решить на sql
24 сообщений из 24, страница 1 из 1
Как решить на sql
    #39799414
tira mi su
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть некие отрезки a-b с типом 1, которые могут не пересекаться, могут частично или полностью включать друг друга.
Отрезки с типом 1 могут быть закрыты отрезком с типом 2.
Нужно в разрезе каждой даты выделить новые отрезки с учетом истории изменения длин этих отрезков. Как реализовать одним запросом?
Oracle 11.2

Исходные данные:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
      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


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
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;



Нужно получить:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
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


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
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;

...
Рейтинг: 0 / 0
Как решить на sql
    #39799435
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tira mi su,

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

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

....
stax
...
Рейтинг: 0 / 0
Как решить на sql
    #39799438
tira mi su
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Забыл указать столбец типа результата...
Нужно получить:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
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


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
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;

...
Рейтинг: 0 / 0
Как решить на sql
    #39799445
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Слава богу.... А то я думал, что с ума сошёл
...
Рейтинг: 0 / 0
Как решить на sql
    #39799447
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tira mi su,

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


.....
stax
...
Рейтинг: 0 / 0
Как решить на sql
    #39799449
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хотя по колонке с описанием вопросы остались
...
Рейтинг: 0 / 0
Как решить на sql
    #39799553
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а зачем это делать одним запросом?
...
Рейтинг: 0 / 0
Как решить на sql
    #39799574
tira mi su
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andreymxа зачем это делать одним запросом?
Академический интерес. Реально ли и если реально, то посмотреть решение. Сам не осилил.
...
Рейтинг: 0 / 0
Как решить на sql
    #39799581
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tira mi suandreymxа зачем это делать одним запросом?
Академический интерес. Реально ли и если реально, то посмотреть решение. Сам не осилил.

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

....
stax
...
Рейтинг: 0 / 0
Как решить на sql
    #39799596
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Staxtira mi suпропущено...

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

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

....
staxи разъединения :)
тип 2 не забываем
...
Рейтинг: 0 / 0
Как решить на sql
    #39799602
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А если добавлены сразу два пересекающихся отрезка, как отображать
...
Рейтинг: 0 / 0
Как решить на sql
    #39799645
Фотография Щукина Анна
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tira mi su,

Ознакомьтесь . Может подчерпнете для себя идею реализации...
...
Рейтинг: 0 / 0
Как решить на sql
    #39799680
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
tira mi su,

что-то хреново с постановкой задачи и примером.
tira mi suНужно получить:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
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


Посмотри на картинку и объясни как, что и откуда должно появляться
...
Рейтинг: 0 / 0
Как решить на sql
    #39799681
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
tira mi su,

сравни с результатом этого запроса:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
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_END11976-11-301689169211979-11-041688168911979-11-041689169211979-11-041692169511982-11-041674.5168311982-11-041686.5168811982-11-041688168911982-11-041689169111982-11-041691169211982-11-041692169511982-11-051674.5168311982-11-051686.51686.611982-11-051686.6168811982-11-051688168911982-11-051689169111982-11-051691169211982-11-051692169511982-11-0516951695.112001-04-271673.51674.512001-04-271674.5168312001-04-2716831683.512001-04-271686.51686.612001-04-271686.6168812001-04-271688168912001-04-271689169112001-04-271691169212001-04-271692169512001-04-2716951695.112010-04-121673.51674.512010-04-121674.5168312010-04-1216831683.512010-04-121686.51686.612010-04-121686.6168812010-04-121688168912010-04-121689169022010-04-121690169422010-04-121694169512010-04-1216951695.112012-12-011673.51674.512012-12-011674.5168312012-12-0116831683.512012-12-011686.51686.612012-12-011686.6168812012-12-011688168912012-12-011689169022012-12-011690169112012-12-011691169212012-12-011692169212012-12-011692169312012-12-011693169422012-12-011694169512012-12-0116951695.1
...
Рейтинг: 0 / 0
Как решить на sql
    #39799719
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtendertira mi su,
что-то хреново с постановкой задачи и примером.

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

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

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

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

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

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

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



.....
stax
...
Рейтинг: 0 / 0
Как решить на sql
    #39799729
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
что-то в таком видеStaxимхо для теста проще пример делать на небольших целых числах (напр с 1 по то 100)
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
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

TYPEDTABVIS101/01/200147----###-102/01/200168------##103/01/200112-#------103/01/200135---##---
Код: plaintext
1.
2.
3.
4.
5.
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	---##---
...
Рейтинг: 0 / 0
Как решить на sql
    #39799733
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreymxчто-то в таком виде

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

.....
stax
...
Рейтинг: 0 / 0
Как решить на sql
    #39799741
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreymxчто-то в таком виде

a-b включно
чутку подправил
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
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
...
Рейтинг: 0 / 0
Как решить на sql
    #39799851
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Staxя понял задачу так
тип 1
0) обьеденяем интервалы первого дня (в примере один интервл то пропускаем)
1) идем по днях (начинаем со второго 04.11.1979 )
2) обьеденяем интервалы текущего дня с результатом расчета предыдущего (все итервалы с начала по текущий)
3) следующий день и п2из исходного примера видно, что сворачивать/объединять интервалы не нужно. Наоборот, их надо разбить


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

Исходную задачу можно еще решить геморройным рекурсивным with, но на большом кол-ве строк это умрет
...
Рейтинг: 0 / 0
Как решить на sql
    #39799885
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtenderИсходную задачу можно еще решить геморройным рекурсивным with, но на большом кол-ве строк это умретТС вроде говорил об академическом интересе
...
Рейтинг: 0 / 0
Как решить на sql
    #39799934
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtenderпро что речь? если про разложение интервала в список точек с помощью генераторов с последующей сверткой

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

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

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

.....
stax
...
Рейтинг: 0 / 0
Как решить на sql
    #39800174
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Staxесли "их надо разбить", то к-во должно увеличиватся (как в Вашем решении),
но для 05.11.1982 их всего 4за 05.11.1982 было 2, а стало 4 - разве это не увеличение? другое дело, что по постановке задаче и примеру с другими строками(например, за 04.11.1979), должно быть еще больше, но, видимо, "потеряли"... Я же выше уже спрашивал:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
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
...
Рейтинг: 0 / 0
Как решить на sql
    #39800355
tira mi su
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Конечно ваши замечания по предоставленному мной результату верные. У каждого отрезка есть свои атрибуты, которые дополнительно вычисляются у результирующих отрезков, поэтому замечания "04.11.1982 1688 1691 -- почему сразу 1691? куда 1689 потеряли?" верные. Например, один из дополнительных атрибутов(кол-во точек) нового отрезка должен вычисляться как максимальное значение за историю жизни этого кусочка от начала жизни до текущей строки. Смежные отрезки с одинаковыми атрибутами, в конечном итоге нужно будет соединить. Также нужно учитывать интервалы с типом "закрыт". После появления вторичного отрезка начинается занового его жить, но только в переделе интервала закрыт. Т.е. он может быть добавлен, пересечен и т.д. до следующего частичного или полного закрытия. Если вторичный отрезок больше закрытого, то учитывается история с самого начала.

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

Прошу прощение, за то что выпал из топика. Был занят неотложными делами.
Постараюсь на выходных более наглядно сформулировать постановку с картинками и нормальными данными. Спасибо за понимание.
...
Рейтинг: 0 / 0
Как решить на sql
    #39800367
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tira mi suПрошу прощение, за то что выпал из топика. Был занят неотложными делами.Да ладно, некоторые готовы чуть ли не платить зарплату, лишь бы их закидывали неправильно сформулированными задачами.
...
Рейтинг: 0 / 0
24 сообщений из 24, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Как решить на sql
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]