Гость
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Запрос на диапазоны дат / 13 сообщений из 13, страница 1 из 1
23.01.2020, 18:47
    #39918058
verter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос на диапазоны дат
Здравствуйте.

Имеется график отпусков сотрудника:

date_bgn - дата начала отпуска
date_end - дата окончания отпуска

на входе вот такой график:

Код: plsql
1.
select date_bgn, date_end from rest_charts



date_bgn date_end
-------------------------
12.01.2020 17.01.2020
28.01.2020 05.02.2020
15.02.2020 22.02.2020

на выходе надо разбить график по месяцам:

date_bgn date_end
-------------------------
12.01.2020 17.01.2020
28.01.2020 31.01.2020
01.02.2020 05.02.2020
15.02.2020 22.02.2020

Как лучше написать запрос так чтобы сделать такое преобразование?
...
Рейтинг: 0 / 0
24.01.2020, 04:49
    #39918158
Щукина Анна
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос на диапазоны дат
verter,

если есть таблица-календарь - то просто пересечь календарь с графиками отпусков. Если таблицы-календаря нет - сделать его в виде встроенного представления на уровне запроса, а далее - по схеме, когда календарь есть...
...
Рейтинг: 0 / 0
24.01.2020, 04:51
    #39918159
Щукина Анна
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос на диапазоны дат
verter,

в вашем случае достаточно не полного календаря, а "обрезка" с первыми числами месяцев...
...
Рейтинг: 0 / 0
24.01.2020, 04:53
    #39918160
Щукина Анна
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос на диапазоны дат
verter,

Ссылка , для вдохновения, на случай создания календарика запросом...
...
Рейтинг: 0 / 0
24.01.2020, 15:04
    #39918407
verter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос на диапазоны дат
спасибо!

если соединять с календарём, то нужно делать так:

Код: 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.
with
  r as
    (select to_date('12.01.2020','dd.mm.yyyy') date_bgn,
            to_date('17.01.2020','dd.mm.yyyy') date_end
     from dual
     union
     select to_date('28.01.2020','dd.mm.yyyy') date_bgn,
            to_date('05.02.2020','dd.mm.yyyy') date_end
     from dual
     union
     select to_date('15.02.2020','dd.mm.yyyy') date_bgn,
            to_date('22.02.2020','dd.mm.yyyy') date_end
     from dual
    ),
  c as
    (
     select to_date('01.01.2020','dd.mm.yyyy') d_bgn,
            to_date('31.01.2020','dd.mm.yyyy') d_end
     from dual
     union
     select to_date('01.02.2020','dd.mm.yyyy') d_bgn,
            to_date('29.02.2020','dd.mm.yyyy') d_end
     from dual
    )

select greatest(r.date_bgn,c.d_bgn) b,
       least(r.date_end,c.d_end) e
from r,c
where (r.date_bgn between c.d_bgn and c.d_end) or
      (r.date_end between c.d_bgn and c.d_end)
order by 1     
...
Рейтинг: 0 / 0
24.01.2020, 15:15
    #39918409
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос на диапазоны дат
verter
спасибо!

если соединять с календарём, то нужно делать так:

Нет
Код: 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.
with
  r as
    (select 1 id,to_date('12.01.2020','dd.mm.yyyy') date_bgn,
            to_date('17.01.2020','dd.mm.yyyy') date_end
     from dual
     union
     select 2,to_date('28.01.2020','dd.mm.yyyy') date_bgn,
            to_date('05.02.2020','dd.mm.yyyy') date_end
     from dual
     union
     select 3,to_date('15.01.2020','dd.mm.yyyy') date_bgn,
            to_date('22.03.2020','dd.mm.yyyy') date_end
     from dual
    ),
  c as
    (
     select to_date('01.01.2020','dd.mm.yyyy') d_bgn,
            to_date('31.01.2020','dd.mm.yyyy') d_end
     from dual
     union
     select to_date('01.02.2020','dd.mm.yyyy') d_bgn,
            to_date('29.02.2020','dd.mm.yyyy') d_end
     from dual
     union
     select to_date('01.03.2020','dd.mm.yyyy') d_bgn,
            to_date('31.03.2020','dd.mm.yyyy') d_end
     from dual
    )
select id,greatest(r.date_bgn,c.d_bgn) b,
       least(r.date_end,c.d_end) e
from r,c
where (r.date_bgn between c.d_bgn and c.d_end) or
      (r.date_end between c.d_bgn and c.d_end)
order by 1,2
SQL> /

        ID B        E
---------- -------- --------
         1 12.01.20 17.01.20
         2 28.01.20 31.01.20
         2 01.02.20 05.02.20
         3 15.01.20 31.01.20
         3 01.03.20 22.03.20



ps
проще размножить (connect by, xml, ітд)

....
stax
...
Рейтинг: 0 / 0
24.01.2020, 19:41
    #39918545
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос на диапазоны дат
Щукина Анна
verter,

Ссылка , для вдохновения, на случай создания календарика запросом...


А зачем тут "календарик", разве если уже есть в наличии?

Код: 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.
with sample_data as (
                     select 1 id,date '2020-01-12' date_bgn,date '2020-01-17' date_end from dual union all
                     select 2 id,date '2020-01-28' date_bgn,date '2020-02-05' date_end from dual union all
                     select 3 id,date '2020-01-15' date_bgn,date '2020-03-22' date_end from dual
                    )
select  id,
        greatest(date_bgn,month_bgn) b,
        least(date_end,month_end) e
  from  sample_data,
        lateral(
                select  add_months(trunc(date_bgn,'mm'),level - 1) month_bgn,
                        last_day(add_months(trunc(date_bgn,'mm'),level - 1)) month_end
                  from  dual
                  connect by level <= months_between(trunc(date_end,'mm'),trunc(date_bgn,'mm')) + 1
               )
/

        ID B         E
---------- --------- ---------
         1 12-JAN-20 17-JAN-20
         2 28-JAN-20 31-JAN-20
         2 01-FEB-20 05-FEB-20
         3 15-JAN-20 31-JAN-20
         3 01-FEB-20 29-FEB-20
         3 01-MAR-20 22-MAR-20

6 rows selected.

SQL>



SY.
...
Рейтинг: 0 / 0
25.01.2020, 08:54
    #39918620
verter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос на диапазоны дат
Stax

ID B E
---------- -------- --------
1 12.01.20 17.01.20
2 28.01.20 31.01.20
2 01.02.20 05.02.20
==> 3 15.01.20 31.01.20
==> 3 01.03.20 22.03.20

[/src]

ps
проще размножить (connect by, xml, ітд)

....
stax


точно!
спасибо, что указали на мою ошибку.
а как размножить с помощью connect by ?
...
Рейтинг: 0 / 0
25.01.2020, 14:38
    #39918676
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос на диапазоны дат
verter
а как размножить с помощью connect by ?


Не читатель? 22066287

SY.
...
Рейтинг: 0 / 0
25.01.2020, 14:40
    #39918678
verter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос на диапазоны дат
SY

А зачем тут "календарик", разве если уже есть в наличии?

Код: 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.
with sample_data as (
                     select 1 id,date '2020-01-12' date_bgn,date '2020-01-17' date_end from dual union all
                     select 2 id,date '2020-01-28' date_bgn,date '2020-02-05' date_end from dual union all
                     select 3 id,date '2020-01-15' date_bgn,date '2020-03-22' date_end from dual
                    )
select  id,
        greatest(date_bgn,month_bgn) b,
        least(date_end,month_end) e
  from  sample_data,
        lateral(
                select  add_months(trunc(date_bgn,'mm'),level - 1) month_bgn,
                        last_day(add_months(trunc(date_bgn,'mm'),level - 1)) month_end
                  from  dual
                  connect by level <= months_between(trunc(date_end,'mm'),trunc(date_bgn,'mm')) + 1
               )
/

        ID B         E
---------- --------- ---------
         1 12-JAN-20 17-JAN-20
         2 28-JAN-20 31-JAN-20
         2 01-FEB-20 05-FEB-20
         3 15-JAN-20 31-JAN-20
         3 01-FEB-20 29-FEB-20
         3 01-MAR-20 22-MAR-20

6 rows selected.

SQL>




SY.


LATERAL или CROSS APPLY работают начиная с 12c версии, у меня 11-я
...
Рейтинг: 0 / 0
25.01.2020, 15:20
    #39918687
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос на диапазоны дат
verter
у меня 11-я


Код: 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 sample_data as (
                     select 1 id,date '2020-01-12' date_bgn,date '2020-01-17' date_end from dual union all
                     select 2 id,date '2020-01-28' date_bgn,date '2020-02-05' date_end from dual union all
                     select 3 id,date '2020-01-15' date_bgn,date '2020-03-22' date_end from dual
                    )
select  id,
        greatest(date_bgn,add_months(trunc(date_bgn,'mm'),level - 1)) b,
        least(date_end,last_day(add_months(trunc(date_bgn,'mm'),level - 1))) e
  from  sample_data
        connect by id = prior id
               and prior sys_guid() is not null
               and level <= months_between(trunc(date_end,'mm'),trunc(date_bgn,'mm')) + 1
/
        ID B         E
---------- --------- ---------
         1 12-JAN-20 17-JAN-20
         2 28-JAN-20 31-JAN-20
         2 01-FEB-20 05-FEB-20
         3 15-JAN-20 31-JAN-20
         3 01-FEB-20 29-FEB-20
         3 01-MAR-20 22-MAR-20

6 rows selected.

SQL>



SY.
...
Рейтинг: 0 / 0
25.01.2020, 15:25
    #39918691
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос на диапазоны дат
Да, ID это не ID сотрудника а уникальное значение записи. Если такого в таблице нет - используй ROWID.

SY.
...
Рейтинг: 0 / 0
25.01.2020, 20:14
    #39918720
verter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос на диапазоны дат
SY

SY.


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


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