Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Опять интервалы :( / 16 сообщений из 16, страница 1 из 1
26.04.2018, 12:47
    #39636706
sharkoff_new
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять интервалы :(
Добрый день
Никак не могу понять подход к решению задачи

Код: 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.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
with t as
 (

  select 1 id,
          
          to_date('01.08.2015', 'dd.mm.yyyy') start_date,
          to_date('14.08.2015', 'dd.mm.yyyy') as end_date,
          1 rnk_id
    from dual
  UNION ALL
  select 1 id,
          
          to_date('07.08.2015', 'dd.mm.yyyy') start_date,
          to_date('08.08.2015', 'dd.mm.yyyy') as end_date,
          2 rnk_id
    from dual
  UNION ALL
  select 1 id,
          
          to_date('09.08.2015', 'dd.mm.yyyy') start_date,
          to_date('10.08.2015', 'dd.mm.yyyy') as end_date,
          3 rnk_id
    from dual
  UNION ALL
  select 1 id,
          
          to_date('12.08.2015', 'dd.mm.yyyy') start_date,
          to_date('22.08.2015', 'dd.mm.yyyy') as end_date,
          4 rnk_id
  
    from dual
  UNION ALL 
  --2 id
  select 2 id,          
          to_date('12.08.2015', 'dd.mm.yyyy') start_date,
          to_date('01.09.2015', 'dd.mm.yyyy') as end_date,
          1 rnk_id
    from dual
  UNION ALL
  select 2 id,          
          to_date('09.08.2015', 'dd.mm.yyyy') start_date,
          to_date('16.08.2015', 'dd.mm.yyyy') as end_date,
          2 rnk_id
  
    from dual
  UNION ALL
  select 2 id,
          
          to_date('13.08.2015', 'dd.mm.yyyy') start_date,
          to_date('18.08.2015', 'dd.mm.yyyy') as end_date,
          3 rnk_id
  
    from dual
  UNION ALL
  select 2 id,
          
          to_date('18.08.2015', 'dd.mm.yyyy') start_date,
          to_date('23.08.2015', 'dd.mm.yyyy') as end_date,
          4 rnk_id
  
    from dual
  UNION ALL
  select 2 id,
          
          to_date('19.08.2015', 'dd.mm.yyyy') start_date,
          to_date('22.08.2015', 'dd.mm.yyyy') as end_date,
          5 rnk_id  
    from dual)
select * from t



Необходимо вычесть все интервалы с rnk_id >1 из интервала с rnk_id=1. При этом
В результате нужно для каждого id получить количество часов- чистого времени.
Благодарен за любые подсказки
...
Рейтинг: 0 / 0
26.04.2018, 14:00
    #39636760
Egoр
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять интервалы :(
тынц
)))):
...
Рейтинг: 0 / 0
26.04.2018, 14:06
    #39636764
sharkoff_new
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять интервалы :(
Egoр,

Не совсем понято чем start -of- group поможет.
...
Рейтинг: 0 / 0
26.04.2018, 14:13
    #39636772
Dshedoo
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять интервалы :(
sharkoff_new,

Разворачиваешь всё в строки, джойнишь rnk_id >1 с rnk_id = 1, возвращаешь всё, что не заджойнилось.
...
Рейтинг: 0 / 0
26.04.2018, 14:15
    #39636775
Egoр
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять интервалы :(
sharkoff_new, там даже задача почти как у тебя.
Код: 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.
with t as
 (select 1 id, to_date('01.08.2015', 'dd.mm.yyyy') start_date, to_date('14.08.2015', 'dd.mm.yyyy') as end_date, 1 rnk_id
    from dual
  UNION ALL
  select 1 id, to_date('07.08.2015', 'dd.mm.yyyy') start_date, to_date('08.08.2015', 'dd.mm.yyyy') as end_date, 2 rnk_id
    from dual
  UNION ALL
  select 1 id, to_date('09.08.2015', 'dd.mm.yyyy') start_date, to_date('10.08.2015', 'dd.mm.yyyy') as end_date, 3 rnk_id
    from dual
  UNION ALL
  select 1 id, to_date('12.08.2015', 'dd.mm.yyyy') start_date, to_date('22.08.2015', 'dd.mm.yyyy') as end_date, 4 rnk_id
    from dual
  UNION ALL
  --2 id
  select 2 id, to_date('12.08.2015', 'dd.mm.yyyy') start_date, to_date('01.09.2015', 'dd.mm.yyyy') as end_date, 1 rnk_id
    from dual
  UNION ALL
  select 2 id, to_date('09.08.2015', 'dd.mm.yyyy') start_date, to_date('16.08.2015', 'dd.mm.yyyy') as end_date, 2 rnk_id
    from dual
  UNION ALL
  select 2 id, to_date('13.08.2015', 'dd.mm.yyyy') start_date, to_date('18.08.2015', 'dd.mm.yyyy') as end_date, 3 rnk_id
    from dual
  UNION ALL
  select 2 id, to_date('18.08.2015', 'dd.mm.yyyy') start_date, to_date('23.08.2015', 'dd.mm.yyyy') as end_date, 4 rnk_id
    from dual
  UNION ALL
  select 2 id, to_date('19.08.2015', 'dd.mm.yyyy') start_date, to_date('22.08.2015', 'dd.mm.yyyy') as end_date, 5 rnk_id
    from dual),
dt0 as
 (select min(start_date) as date_from, max(end_date) as date_to from t),
dt as
 (select date_from + level - 1 as dt from dt0 connect by level <= date_to - date_from + 1),
t1 as
 (select *
    from t
    join dt
      on dt between start_date and end_date
     and rnk_id = 1),
t2 as
 (select t1.*, decode(dt, lag(dt) over(partition by id order by dt) + 1, 0, 1) as sog
    from t1
   where not exists (select *
            from t
           where t.id = t1.id
             and t.rnk_id != 1
             and dt between t.start_date and t.end_date)),
t3 as
 (select t2.*, sum(sog) over(order by id, dt) as grp from t2)
select id, Min(dt) as start_date, Max(dt) as end_date, grp from t3 group by id, grp
...
Рейтинг: 0 / 0
26.04.2018, 14:59
    #39636800
sharkoff_new
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять интервалы :(
Egoр,
Похоже но не то, полученные периоды явно "не мои"
...
Рейтинг: 0 / 0
26.04.2018, 15:15
    #39636811
Egoр
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять интервалы :(
sharkoff_newEgoр,
Похоже но не то, полученные периоды явно "не мои"Приличных слов не нахожу, поэтому от эмоций воздержусь.
Если выдаешь субъективную результирующую часть ("не мои"), то будь ласка, снабжать ее объективной мотивировочной.
...
Рейтинг: 0 / 0
26.04.2018, 19:00
    #39636982
sharkoff_new
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять интервалы :(
Egoр,

Виноват, небольшой цейтнот

По id=1
1 (01.08.2015 - 07.08.2015) *24- засчитываем
1 (07.08.2015 - 08.08.2015) *0 НЕ считаем
1 (08.08.2015 - 09.08.2015) *24 - засчитываем
1 (09.08.2015 -10.08.2015) *0 НЕ засчитываем
1 (10.08.2015 - 12.08.2015) *24 Засчитываем
1 (12.08.2015- 14.08.2015 | как бы 22.08.2015 но интервал с rnk=1 |) * 0 не засчитываем

Т.е суть в том что из большого интервала (rnk=1) вырезать мелкие подинтервалы с (rnk>1) , должны получиться другие мелкие интервалы значимые для итога.
...
Рейтинг: 0 / 0
27.04.2018, 07:33
    #39637101
sharkoff_new
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять интервалы :(
Чуть чуть продвинулся , дальше чего то полет мысли прекратился


Код: 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.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
with t as
 (
  
  select 1 id,
          
          to_date('01.08.2015', 'dd.mm.yyyy') start_date,
          to_date('14.08.2015', 'dd.mm.yyyy') as end_date,
          1 rnk_id
    from dual
  UNION ALL
  select 1 id,
          
          to_date('07.08.2015', 'dd.mm.yyyy') start_date,
          to_date('08.08.2015', 'dd.mm.yyyy') as end_date,
          2 rnk_id
    from dual
  UNION ALL
  select 1 id,
          
          to_date('09.08.2015', 'dd.mm.yyyy') start_date,
          to_date('10.08.2015', 'dd.mm.yyyy') as end_date,
          3 rnk_id
    from dual
  UNION ALL
  select 1 id,
          
          to_date('12.08.2015', 'dd.mm.yyyy') start_date,
          to_date('22.08.2015', 'dd.mm.yyyy') as end_date,
          4 rnk_id
  
    from dual
  UNION ALL
  --2 id
  select 2 id,
          to_date('12.08.2015', 'dd.mm.yyyy') start_date,
          to_date('01.09.2015', 'dd.mm.yyyy') as end_date,
          1 rnk_id
    from dual
  UNION ALL
  select 2 id,
          to_date('09.08.2015', 'dd.mm.yyyy') start_date,
          to_date('16.08.2015', 'dd.mm.yyyy') as end_date,
          2 rnk_id
  
    from dual
  UNION ALL
  select 2 id,
          
          to_date('13.08.2015', 'dd.mm.yyyy') start_date,
          to_date('18.08.2015', 'dd.mm.yyyy') as end_date,
          3 rnk_id
  
    from dual
  UNION ALL
  select 2 id,
          
          to_date('18.08.2015', 'dd.mm.yyyy') start_date,
          to_date('23.08.2015', 'dd.mm.yyyy') as end_date,
          4 rnk_id
  
    from dual
  UNION ALL
  select 2 id,
          
          to_date('19.08.2015', 'dd.mm.yyyy') start_date,
          to_date('22.08.2015', 'dd.mm.yyyy') as end_date,
          5 rnk_id
    from dual),

t$point as
 (select id,
         point as b,
         nvl(lead(point) over(partition by id order by point),
             to_date('01.01.4444', 'dd.mm.yyyy')) as e,
         rnk_id
    from (select id, start_date as point, rnk_id
            from t
          union
          select id, end_date as point, rnk_id
            from t))
select *
  from (select id, start_date, end_date, rnk_id from t where rnk_id = 1) t
  join t$point tp
    on (t.id = tp.id)
 where t.end_date >= tp.e
 order by t.id, tp.rnk_id;
...
Рейтинг: 0 / 0
27.04.2018, 09:09
    #39637136
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять интервалы :(
sharkoff_new,

о, моя любимая тема
недовно было, лень искать, проще набрать
Код: 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.
with t (id,start_date,end_date,rnk_id) as (
select 1,date '2018-03-05',date '2018-03-25',1 from dual union all
select 1,date '2018-03-10',date '2018-03-15',2 from dual union all
select 1,date '2018-03-10',date '2018-03-13',3 from dual union all
select 1,date '2018-03-12',date '2018-03-20',4 from dual union all
select 1,date '2018-03-24',date '2018-04-20',5 from dual union all
select 1,date '2018-02-24',date '2018-03-06',6 from dual union all
select 2,date '2018-03-05',date '2018-03-25',1 from dual union all
select 2,date '2018-02-05',date '2018-03-20',2 from dual union all
select 3,date '2018-03-05',date '2018-03-25',1 from dual union all
select 3,date '2018-03-25',date '2018-04-25',2 from dual 
)
,du as (select 1 p from dual union all select -1 from dual)
, tt as ( --разворачиваем
select 
  id
 ,decode(p,1,start_date,end_date) d
 ,p
 ,decode(rnk_id,1,1,2)*p f
from t,du)
,ttt as ( --start/end могут совпадать, берем раз (distinct)
   select id,d,sum(sum(f)) over (partition by id order by d)  f
   from tt 
   group by id,d)
,tttt as ( --приходится, не хочет  sum(over)
   select ttt.*,lead(d,1,d) over (partition by id order by d) le from ttt)
select id,sum(le-d) i --сумируем чистые интервальчики
from tttt
where f=1
group by id
order by 1
/

SQL> /

        ID          I
---------- ----------
         1          8
         2          5
         3         20



.....
stax
...
Рейтинг: 0 / 0
27.04.2018, 09:41
    #39637158
Egoр
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять интервалы :(
sharkoff_newEgoр,

Виноват, небольшой цейтнот

По id=1
I 1 (01.08.2015 - 07.08.2015 ) *24- засчитываем
II 1 ( 07.08.2015 - 08.08.2015) *0 НЕ считаем
1 (08.08.2015 - 09.08.2015) *24 - засчитываем
1 (09.08.2015 -10.08.2015) *0 НЕ засчитываем
1 (10.08.2015 - 12.08.2015) *24 Засчитываем
1 (12.08.2015- 14.08.2015 | как бы 22.08.2015 но интервал с rnk=1 |) * 0 не засчитываем

Т.е суть в том что из большого интервала (rnk=1) вырезать мелкие подинтервалы с (rnk>1) , должны получиться другие мелкие интервалы значимые для итога.Требуется уточнение о строгости определения границ интервалов.
Например, дата 07.08.2015 указана в качестве границы и в строке I и в строке II.
Но не указано в какой ОДНОЙ из этих строк она должна быть учтена.
Т.к. для проверки интервалов я предпочитаю использовать between, то, по-умолчанию, считаю,
что интервалы дат включают обе границы.
...
Рейтинг: 0 / 0
27.04.2018, 11:56
    #39637298
sharkoff_new
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять интервалы :(
Stax,

Супер! Снимаю шляпу!
...
Рейтинг: 0 / 0
27.04.2018, 12:29
    #39637347
sharkoff_new
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять интервалы :(
Stax,
Подскажите пожалуйста, для понимания, а каков физический смысл поля F
здесь
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
tt as
 ( --разворачиваем
  select id,
          decode(p, 1, start_date, end_date) d,
          p,
         decode(rnk_id, 1, 1, 2) * p f, -- вот тут
          rnk_id
    from t, du)



?
...
Рейтинг: 0 / 0
27.04.2018, 12:58
    #39637382
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять интервалы :(
sharkoff_new,

Вам ж надо не просто обьеденить пересекающиеся интервалы,
а как-то идентифицировать главный (rnk_id=1) c учетом уровня вложенности
для первого "вес" 1, для всех других напр 2

где-то так

.....
stax
...
Рейтинг: 0 / 0
27.04.2018, 13:16
    #39637414
MaximaXXL
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять интервалы :(
sharkoff_new,

А можно прям в тупую =)

Код: 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.
with t (id,start_date,end_date,rnk_id) as (
select 1,date '2018-03-05',date '2018-03-25',1 from dual union all
select 1,date '2018-03-10',date '2018-03-15',2 from dual union all
select 1,date '2018-03-10',date '2018-03-13',3 from dual union all
select 1,date '2018-03-12',date '2018-03-20',4 from dual union all
select 1,date '2018-03-24',date '2018-04-20',5 from dual union all
select 1,date '2018-02-24',date '2018-03-06',6 from dual union all
select 2,date '2018-03-05',date '2018-03-25',1 from dual union all
select 2,date '2018-02-05',date '2018-03-20',2 from dual union all
select 3,date '2018-03-05',date '2018-03-25',1 from dual union all
select 3,date '2018-03-25',date '2018-04-25',2 from dual 
)
(select id, start_date + level - 1 List_date  from t 
where rnk_id = 1
connect by id = prior id 
       and rnk_id = prior rnk_id
       and level <= (end_date - start_date) +1
       and prior dbms_random.value is not null)
minus
(select id, start_date + level - 1 List_date  from t 
where rnk_id != 1
connect by id = prior id 
       and rnk_id = prior rnk_id
       and level <= (end_date - start_date) +1
       and prior dbms_random.value is not null)



Но решение Стаса мне нравиться больше =)
...
Рейтинг: 0 / 0
27.04.2018, 14:01
    #39637466
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Опять интервалы :(
MaximaXXL,

дата со временем (timestamp)

мне с date проще проверять результат было

к стати, так и забыл умножить на 24


.....
stax
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Опять интервалы :( / 16 сообщений из 16, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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