powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Запрос на диапазоны дат
13 сообщений из 13, страница 1 из 1
Запрос на диапазоны дат
    #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
Запрос на диапазоны дат
    #39918158
Фотография Щукина Анна
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
verter,

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

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

Ссылка , для вдохновения, на случай создания календарика запросом...
...
Рейтинг: 0 / 0
Запрос на диапазоны дат
    #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
Запрос на диапазоны дат
    #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
Запрос на диапазоны дат
    #39918545
Фотография 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
Запрос на диапазоны дат
    #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
Запрос на диапазоны дат
    #39918676
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
verter
а как размножить с помощью connect by ?


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

SY.
...
Рейтинг: 0 / 0
Запрос на диапазоны дат
    #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
Запрос на диапазоны дат
    #39918687
Фотография 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
Запрос на диапазоны дат
    #39918691
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, ID это не ID сотрудника а уникальное значение записи. Если такого в таблице нет - используй ROWID.

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

SY.


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


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