powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Опять интервалы :(
16 сообщений из 16, страница 1 из 1
Опять интервалы :(
    #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
Опять интервалы :(
    #39636760
Фотография Egoр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
тынц
)))):
...
Рейтинг: 0 / 0
Опять интервалы :(
    #39636764
sharkoff_new
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Egoр,

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

Разворачиваешь всё в строки, джойнишь rnk_id >1 с rnk_id = 1, возвращаешь всё, что не заджойнилось.
...
Рейтинг: 0 / 0
Опять интервалы :(
    #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
Опять интервалы :(
    #39636800
sharkoff_new
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Egoр,
Похоже но не то, полученные периоды явно "не мои"
...
Рейтинг: 0 / 0
Опять интервалы :(
    #39636811
Фотография Egoр
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sharkoff_newEgoр,
Похоже но не то, полученные периоды явно "не мои"Приличных слов не нахожу, поэтому от эмоций воздержусь.
Если выдаешь субъективную результирующую часть ("не мои"), то будь ласка, снабжать ее объективной мотивировочной.
...
Рейтинг: 0 / 0
Опять интервалы :(
    #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
Опять интервалы :(
    #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
Опять интервалы :(
    #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
Опять интервалы :(
    #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
Опять интервалы :(
    #39637298
sharkoff_new
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Stax,

Супер! Снимаю шляпу!
...
Рейтинг: 0 / 0
Опять интервалы :(
    #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
Опять интервалы :(
    #39637382
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sharkoff_new,

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

где-то так

.....
stax
...
Рейтинг: 0 / 0
Опять интервалы :(
    #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
Опять интервалы :(
    #39637466
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximaXXL,

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

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

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


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


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