powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Connect by prior с прерыванием промежутков
8 сообщений из 8, страница 1 из 1
Connect by prior с прерыванием промежутков
    #39779845
ВЕЗУНЧИК
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем привет, нужна помощь в написании элегантного запроса, несколько часов пытаюсь победить и пока никак.
Задача: есть временные пересекающиеся промежутки с пробелами:

04.02.2018-08.02.2018
09.02.2018-11.02.2018
11.02.2018-13.02.2018
13.02.2018-14.02.2018
15.02.2018-18.02.2018
18.02.2018-01.02.2018

нужно найти концы последовательно пересекающихся промежутков в который попадает определенная дата без прерывания, например 12.02.2018 попадает в промежуток 11.02.2018-13.02.2018, этот промежуток непрерывно связан с промежутками:
09.02.2018-11.02.2018 - 11.02.2018-13.02.2018 - 13.02.2018-14.02.2018, результат в данном случае должен быть промежуток: 09.02.2018 -14.02.2018

Данный промежуток нужно получить одним запросом, без использования конструкции WITH:

что-то типа:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
/*select * from 
(*/select min(d1), max(d2)/*, level, CONNECT_BY_ISLEAF*/
 from
(select to_date('04.02.2018', 'dd.mm.yyyy') d1, to_date('08.02.2018', 'dd.mm.yyyy') d2 from dual union
 select  to_date('09.02.2018', 'dd.mm.yyyy') d1, to_date('11.02.2018', 'dd.mm.yyyy') d2 from dual union
 select  to_date('11.02.2018', 'dd.mm.yyyy') d1, to_date('13.02.2018', 'dd.mm.yyyy') d2 from dual union
 select  to_date('13.02.2018', 'dd.mm.yyyy') d1, to_date('14.02.2018', 'dd.mm.yyyy') d2 from dual union 

 select  to_date('15.02.2018', 'dd.mm.yyyy') d1, to_date('18.02.2018', 'dd.mm.yyyy') d2 from dual union 
 select  to_date('18.02.2018', 'dd.mm.yyyy') d1, to_date('01.02.2018', 'dd.mm.yyyy') d2 from dual) p  
 connect by prior d1=d2 and level>0
 start with (d1<=to_date('12.02.2018', 'dd.mm.yyyy') 
                                    and d2>to_date('12.02.2018', 'dd.mm.yyyy')) 
                                    or (d1>to_date('12.02.2018', 'dd.mm.yyyy'))/*)*/ 



но в данном случае возвращается промежуток 09.02.2018 - 18.02.2018, что не корректно.
...
Рейтинг: 0 / 0
Connect by prior с прерыванием промежутков
    #39779850
Фотография Щукина Анна
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВЕЗУНЧИК,

Вот вы сейчас такой баян расчехлили, что я не удивлюсь, если вас с головой закидают ссаными тряпками...
...
Рейтинг: 0 / 0
Connect by prior с прерыванием промежутков
    #39779901
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВЕЗУНЧИКВсем привет, нужна помощь в написании элегантного запроса, несколько часов пытаюсь победить и пока никак.

несколько часов на написании элегантного запроса, маловато

если не елегантно, то обьеденить интервальчики, и выдать с нужной датой

....
stax
...
Рейтинг: 0 / 0
Connect by prior с прерыванием промежутков
    #39779912
ВЕЗУНЧИК
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Щукина Анна,

Да задача не для слабонервных ;) и если кроме "санымх тряпок" в голове ничего, то лучше уж не писать коммент.
...
Рейтинг: 0 / 0
Connect by prior с прерыванием промежутков
    #39779937
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВЕЗУНЧИКпересекающиеся промежуткисмежные
...
Рейтинг: 0 / 0
Connect by prior с прерыванием промежутков
    #39779947
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
-2-смежные
для смежных задача упрощается
Код: 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.
  1  with w (start_date, end_date) as (
  2   select to_date('04.02.2018', 'dd.mm.yyyy') d1, to_date('08.02.2018', 'dd.mm.yyyy') d2 from dual union
  3   select  to_date('09.02.2018', 'dd.mm.yyyy') d1, to_date('11.02.2018', 'dd.mm.yyyy') d2 from dual union
  4   select  to_date('11.02.2018', 'dd.mm.yyyy') d1, to_date('13.02.2018', 'dd.mm.yyyy') d2 from dual union
  5   select  to_date('13.02.2018', 'dd.mm.yyyy') d1, to_date('14.02.2018', 'dd.mm.yyyy') d2 from dual union
  6   select  to_date('15.02.2018', 'dd.mm.yyyy') d1, to_date('18.02.2018', 'dd.mm.yyyy') d2 from dual union
  7   select  to_date('18.02.2018', 'dd.mm.yyyy') d1, to_date('01.02.2018', 'dd.mm.yyyy') d2 from dual)
  8  --
  9  -- Основной запрос:
 10  select
 11    min(START_DATE) d_from
 12   ,max(END_DATE)   d_to
 13  from
 14   (select
 15     START_DATE
 16    ,END_DATE
 17    ,sum(END_DATE-START_DATE) over (order by START_DATE) d
 18    from w) t
 19  group by END_DATE-d
 20* having date '2018-02-12' between min(START_DATE) and max(END_DATE)
SQL> /

D_FROM   D_TO
-------- --------
09.02.18 14.02.18



.....
stax
...
Рейтинг: 0 / 0
Connect by prior с прерыванием промежутков
    #39779960
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВЕЗУНЧИКно в данном случае возвращается промежуток 09.02.2018 - 18.02.2018, что не корректно.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
select  min(d1) d1,
        max(d2) d2
  from  p  
  start with date '2018-02-12' between d1 and d2
  connect by nocycle prior d1 = d2
                  or prior d2 = d1
/

D1        D2
--------- ---------
09-FEB-18 14-FEB-18

SQL> 



SY.
...
Рейтинг: 0 / 0
Connect by prior с прерыванием промежутков
    #39780281
ВЕЗУНЧИК
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SY, я благодарю тебя! Выше всех похвал!!! То что нужно. Я даже не знал, что "connect by" может пойти в обе стороны от start with. nocycle - это как я понимаю прерывание в случае зацикливания. Еще раз спасибо.
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Connect by prior с прерыванием промежутков
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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