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

Откуда:
Сообщений: 175
Есть две таблички интервалов graph(begin_, end_) и data(begin_, end_). Нужно из graph sql запросом выделить интервалы, которые не пересекаются с data. В задаче begin_ и end_ даты, поэтому целочисленностью пользоваться нельзя.
with
data as
(select 20 as begin_, 30 as end_ from dual
 union all
 select 40 as begin_, 50 as end_ from dual
 union all
 select 90 as begin_, 120 as end_ from dual),
graph as
(select 10 as begin_, 100 as end_ from dual
 union all
 select 110 as begin_, 200 as end_ from dual)

Для данного набора результат должен быть таким:
begin_            end_
10                20
30                40
90                100
110               120
12 апр 07, 07:09    [4009629]     Ответить | Цитировать Сообщить модератору
 Re: Непересекающиеся интервалы  [new]
kennethr
Member

Откуда:
Сообщений: 175
Ошибся, результат:
begin_            end_
10                20
30                40
50                90
120               200
12 апр 07, 07:11    [4009630]     Ответить | Цитировать Сообщить модератору
 Re: Непересекающиеся интервалы  [new]
Бабичев Сергей
Member

Откуда:
Сообщений: 2498
Может чем поможет: тынц - непересекающиеся интервалы
12 апр 07, 07:31    [4009640]     Ответить | Цитировать Сообщить модератору
 Re: Непересекающиеся интервалы  [new]
GKS_Samara
Member

Откуда: Самара
Сообщений: 2790

> В задаче begin_ и end_ даты, поэтому целочисленностью пользоваться
нельзя.
Можно, если представить даты в виде чисел
select to_number(to_char(sysdate,'yyyymmddhh24miss')) date_number from dual






Posted via ActualForum NNTP Server 1.4

12 апр 07, 09:40    [4009980]     Ответить | Цитировать Сообщить модератору
 Re: Непересекающиеся интервалы  [new]
GKS_Samara
Member

Откуда: Самара
Сообщений: 2790

Дальнейшее решение нужно?


Posted via ActualForum NNTP Server 1.4

12 апр 07, 09:40    [4009983]     Ответить | Цитировать Сообщить модератору
 Re: Непересекающиеся интервалы  [new]
kennethr
Member

Откуда:
Сообщений: 175
GKS_Samara

Дальнейшее решение нужно?

Не откажусь, так как идеи совершенно не понял. Я говорил о том, что числовой ряд не дискретный.
12 апр 07, 09:55    [4010075]     Ответить | Цитировать Сообщить модератору
 Re: Непересекающиеся интервалы  [new]
Elic
Member

Откуда:
Сообщений: 29987
with
data as
( select 20 as begin_, 30 as end_ from dual
  union all
  select 40 as begin_, 50 as end_ from dual
  union all
  select 90 as begin_, 120 as end_ from dual
),
graph as
( select 10 as begin_, 100 as end_ from dual
  union all
  select 110 as begin_, 200 as end_ from dual
),
i1 as
( select *
    from
    ( select point as b, lead(point) over (order by point) as e
        from
        ( select begin_ as point from data
          union
          select end_   as point from data
          union
          select begin_ as point from graph
          union
          select end_   as point from graph
        )
    )
    where e is not null
)
select b, e from i1
  where not exists
    ( select null from data
        where b >= begin_ and e <= end_
    )
;

            B             E
------------- -------------
           10            20
           30            40
           50            90
          120           200
12 апр 07, 10:14    [4010243]     Ответить | Цитировать Сообщить модератору
 Re: Непересекающиеся интервалы  [new]
kennethr
Member

Откуда:
Сообщений: 175
Всем спасибо. Отвечаю сам себе:
with
data as
(select 1 as id, 20 as begin_, 30 as end_ from dual
 union all
 select 2 as id, 40 as begin_, 50 as end_ from dual
 union all
 select 3 as id, 90 as begin_, 120 as end_ from dual),
graph as
(select 1 as id, 10 as begin_, 100 as end_ from dual
 union all
 select 2 as id, 110 as begin_, 200 as end_ from dual)


select prev_begin_ as begin_,
       begin_ as end_
  from (select nvl(lag(d.end_) over (partition by g.id order by d.begin_, d.end_),g.begin_) as prev_begin_,
               d.begin_,
               d.end_
          from data d,
               graph g
         where ((d.begin_ >= g.begin_ and d.begin_ < g.end_) or
                (d.end_ > g.begin_ and d.end_ <= g.end_))
       )
 where prev_begin_ < begin_
union
select end_ as begin_,
       next_end_ as end_
  from (select d.begin_,
               d.end_,
               nvl(lead(d.begin_) over (partition by g.id order by d.begin_, d.end_),g.end_) as next_end_
          from data d,
               graph g
         where ((d.begin_ >= g.begin_ and d.begin_ < g.end_) or
                (d.end_ > g.begin_ and d.end_ <= g.end_))
       )
 where next_end_ > end_
12 апр 07, 10:17    [4010278]     Ответить | Цитировать Сообщить модератору
 Re: Непересекающиеся интервалы  [new]
Elic
Member

Откуда:
Сообщений: 29987
kennethr
Отвечаю сам себе
Черезчур сложно, как следствие неправильно:
graph as ... select 300 as begin_, 500 as end_ from dual

select b, e from i1
  where not exists
    ( select null from data
        where b >= begin_ and e <= end_
    )
  and exists
    ( select null from graph
        where b >= begin_ and e <= end_
    )
12 апр 07, 10:36    [4010441]     Ответить | Цитировать Сообщить модератору
 Re: Непересекающиеся интервалы  [new]
kennethr
Member

Откуда:
Сообщений: 175
Elic

Спасибо. Elic как всегда в ударе.
12 апр 07, 11:14    [4010788]     Ответить | Цитировать Сообщить модератору
 Re: Непересекающиеся интервалы  [new]
Volder
Member

Откуда: Москва
Сообщений: 474
Elic

SQL> with
  2  data as
  3  ( select 20 as begin_, 30 as end_ from dual
  4    union all
  5    select 40 as begin_, 50 as end_ from dual
  6    union all
  7    select 90 as begin_, 120 as end_ from dual
  8  ),
  9  graph as
 10  ( select 10 as begin_, 100 as end_ from dual
 11    union all
 12    select 110 as begin_, 200 as end_ from dual
 13    union all
 14    select 220 as begin_, 300 as end_ from dual
 15  ),
 16  i1 as
 17  ( select *
 18      from
 19      ( select point as b, lead(point) over (order by point) as e
 20          from
 21          ( select begin_ as point from data
 22            union
 23            select end_   as point from data
 24            union
 25            select begin_ as point from graph
 26            union
 27            select end_   as point from graph
 28          )
 29      )
 30      where e is not null
 31  )
 32  --
 33  select b, e from i1
 34    where not exists
 35      ( select null from data
 36          where b >= begin_ and e <= end_
 37      )
 38  /

         B          E
---------- ----------
        10         20
        30         40
        50         90
       120        200
       200        220
       220        300

6 rows selected

SQL> 

лечится добавлением
  and exists(select null from graph
        where b>= begin_ and e <= end_)
12 апр 07, 17:36    [4013772]     Ответить | Цитировать Сообщить модератору
 Re: Непересекающиеся интервалы  [new]
Volder
Member

Откуда: Москва
Сообщений: 474
Elic

select b, e from i1
  where not exists
    ( select null from data
        where b >= begin_ and e <= end_
    )
  and exists
    ( select null from graph
        where b >= begin_ and e <= end_
    )


пардон, проскочил
12 апр 07, 17:42    [4013824]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить