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

Откуда:
Сообщений: 2142
Есть таблица с датами:
with int_dt (dt) as
(
select TO_DATE('10.10.2014', 'DD.MM.YYYY') from dual
union all
select TO_DATE('15.10.2014', 'DD.MM.YYYY') from dual
union all
select TO_DATE('30.10.2014', 'DD.MM.YYYY') from dual
)
....

мне необходиом получит таблицу вида:
dt1dt2
null 10.10.2014
10.10.2014 15.10.2014
15.10.2014 30.10.2014
30.10.2014 null


Мое решение:
SELECT null, MIN(dt)  FROM int_dt
union all
SELECT  dt1,
            dt2
    FROM
    (
        SELECT dt dt1,
                ( SELECT dt
                  FROM
                    ( SELECT dt, ROWNUM rn FROM int_dt ORDER BY dt
                    )
                  WHERE rn = a.rn1 + 1
                ) dt2
        FROM
          ( SELECT dt, ROWNUM rn1 FROM int_dt
          ) a
    )
union all
SELECT MAX(dt), null FROM int_dt


Можно ли более оптимально это решить?

Большое спасибо
18 дек 14, 16:44    [17018242]     Ответить | Цитировать Сообщить модератору
 Re: Разбить на участки дат  [new]
AmKad
Member

Откуда:
Сообщений: 5222
kasik,

lag/lead
18 дек 14, 16:54    [17018313]     Ответить | Цитировать Сообщить модератору
 Re: Разбить на участки дат  [new]
SY
Member

Откуда: Middlebury, CT USA
Сообщений: 10043
kasik,

SQL> with int_dt(dt) as (
  2                      select DATE '2014-10-10' from dual union all
  3                      select DATE '2014-10-15' from dual union all
  4                      select DATE '2014-10-30' from dual
  5                     )
  6  select  lag(dt) over(order by dt nulls last) dt1,
  7          dt
  8    from  (
  9            select * from int_dt
 10           union all
 11            select null from dual
 12          )
 13  /

DT1       DT
--------- ---------
          10-OCT-14
10-OCT-14 15-OCT-14
15-OCT-14 30-OCT-14
30-OCT-14

SQL> 


SY.

Сообщение было отредактировано: 18 дек 14, 16:56
18 дек 14, 16:55    [17018330]     Ответить | Цитировать Сообщить модератору
 Re: Разбить на участки дат  [new]
kasik
Member

Откуда:
Сообщений: 2142
Ну как всегда аналитика рулит, не пришлось применять данную ф-ю, и вот пришло время, спасибо за наводку.
Но если необходимо усложнить: закончить текущей датай и начать с какой то вычисленной.
Мое решение:
with int_dt(dt) as (
                      select DATE '2014-10-10' from dual union all
                      select DATE '2014-10-15' from dual union all
                      select DATE '2014-10-30' from dual
                     )
SELECT * FROM (
  select  lag(dt) over(order by dt) dt1,
          dt
    from  (select MIN(dt) - 1 dt from int_dt
            union all
            select dt from int_dt
           union all
            select SYSdate from dual
          )
    )
  WHERE dt1 IS NOT null


Оптимизировать больше некуда?

Спасибо
18 дек 14, 17:05    [17018404]     Ответить | Цитировать Сообщить модератору
 Re: Разбить на участки дат  [new]
kasik
Member

Откуда:
Сообщений: 2142
или так:
with int_dt(dt) as (
                      select DATE '2014-10-10' from dual union all
                      select DATE '2014-10-15' from dual union all
                      select DATE '2014-10-30' from dual
                     )
  select  case 
            when (lag(dt) over(order by dt)) IS NULL THEN 
            (select MIN(dt) - 1 dt1 from int_dt) 
          else 
            (lag(dt) over(order by dt)) 
          end dt1,
          dt
    from  (
            select dt from int_dt
           union all
            select SYSdate from dual
          )
18 дек 14, 17:09    [17018427]     Ответить | Цитировать Сообщить модератору
 Re: Разбить на участки дат  [new]
stax..
Guest
kasik,

lag имеет три параметра
  1  with int_dt(dt) as (
  2                        select DATE '2014-10-10' from dual union all
  3                        select DATE '2014-10-15' from dual union all
  4                        select DATE '2014-10-30' from dual
  5                       )
  6    select  lag(dt,1,dt-1) over(order by dt nulls last) dt1,
  7            nvl(dt,sysdate)
  8      from  (
  9              select * from int_dt
 10             union all
 11              select null from dual
 12*           )
 13  /

DT1      NVL(DT,S
-------- --------
09.10.14 10.10.14
10.10.14 15.10.14
15.10.14 30.10.14
30.10.14 18.12.14


.......
stax
18 дек 14, 17:29    [17018540]     Ответить | Цитировать Сообщить модератору
 Re: Разбить на участки дат  [new]
kasik
Member

Откуда:
Сообщений: 2142
Вообще классно!
Спасибо
18 дек 14, 17:49    [17018657]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить