Гость
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Размножить строки с переносом значения / 7 сообщений из 7, страница 1 из 1
30.06.2021, 12:13
    #40080893
AVP2012
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Размножить строки с переносом значения
Добрый день,
Подскажите пожалуйста, можно ли реализовать такое?
Входные данные:
Код: 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.
Connected to Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 
Connected as test@test
 
SQL> 
WITH calendar AS (select to_date('01.12.2020','dd.mm.yyyy') date_from,
                             to_date('31.12.2020','dd.mm.yyyy') date_to from dual union all
                      select to_date('01.01.2021','dd.mm.yyyy') date_from,
                             to_date('31.01.2021','dd.mm.yyyy') date_to from dual union all
                      select to_date('01.02.2021','dd.mm.yyyy') date_from,
                             to_date('28.02.2021','dd.mm.yyyy') date_to from dual union all
                      select to_date('01.03.2021','dd.mm.yyyy') date_from,
                             to_date('31.03.2021','dd.mm.yyyy') date_to from dual union all
                      select to_date('01.04.2021','dd.mm.yyyy') date_from,
                            to_date('30.04.2021','dd.mm.yyyy') date_to from dual),
         input   AS (select to_date('01.01.2021','dd.mm.yyyy') date_from, 1 c from dual union all
                     select to_date('01.03.2021','dd.mm.yyyy') date_from, 2 c from dual)
   select c.date_from, c.date_to, i.c from calendar c, input i
   order by c.date_from
   /
 
DATE_FROM   DATE_TO              C
----------- ----------- ----------
01.12.2020  31.12.2020           1
01.12.2020  31.12.2020           2
01.01.2021  31.01.2021           1
01.01.2021  31.01.2021           2
01.02.2021  28.02.2021           1
01.02.2021  28.02.2021           2
01.03.2021  31.03.2021           2
01.03.2021  31.03.2021           1
01.04.2021  30.04.2021           2
01.04.2021  30.04.2021           1
 
SQL> 


В результате хотелось бы получить:
DATE_FROM DATE_TO C
----------- ----------- ----------
01.12.2020 31.12.2020 0
01.01.2021 31.01.2021 1
01.02.2021 28.02.2021 1
01.03.2021 31.03.2021 2
01.04.2021 30.04.2021 2

Без дублирования строк, в периоде с 01.12.2020 - 31.12.2020 данных в таблице input нет, т.е. значение 0. Далее появилась запись в input в январе, соответственно значение 1, в феврале в данной таблице записей нет, но календарем ее добавляем и переносим значение января и т.д.

Пробовал так:
Код: plsql
1.
2.
3.
4.
select *
from
(select c.date_from, c.date_to, i.c, lag(i.c) over(partition by c.date_from order by c.date_from) l_c from calendar c, input i order by c.date_from)
where l_c is not null


но первое значение не по результату, да и выглядит хлипко.

Спасибо!
...
Рейтинг: 0 / 0
30.06.2021, 13:05
    #40080908
KATEROK
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Размножить строки с переносом значения
Вот решение:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
WITH calendar AS (select to_date('01.12.2020','dd.mm.yyyy') date_from,
                             to_date('31.12.2020','dd.mm.yyyy') date_to from dual union all
                      select to_date('01.01.2021','dd.mm.yyyy') date_from,
                             to_date('31.01.2021','dd.mm.yyyy') date_to from dual union all
                      select to_date('01.02.2021','dd.mm.yyyy') date_from,
                             to_date('28.02.2021','dd.mm.yyyy') date_to from dual union all
                      select to_date('01.03.2021','dd.mm.yyyy') date_from,
                             to_date('31.03.2021','dd.mm.yyyy') date_to from dual union all
                      select to_date('01.04.2021','dd.mm.yyyy') date_from,
                            to_date('30.04.2021','dd.mm.yyyy') date_to from dual),
         input   AS (select to_date('01.01.2021','dd.mm.yyyy') date_from, 1 c from dual union all
                     select to_date('01.03.2021','dd.mm.yyyy') date_from, 2 c from dual)
select c.date_from, c.date_to,
case when not exists (select 1 from input i2 where i2.date_from <= c.date_from) then 0 else (select max(i2.c) from input i2 where i2.date_from <= c.date_from) end c
from calendar c
left join input i
	on c.date_from = i.date_from
order by c.date_from
...
Рейтинг: 0 / 0
30.06.2021, 13:18
    #40080914
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Размножить строки с переносом значения
AVP2012,

Код: 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.
SQL> ed
Wrote file afiedt.buf

  1  WITH calendar AS (select to_date('01.12.2020','dd.mm.yyyy') date_from,
  2                               to_date('31.12.2020','dd.mm.yyyy') date_to from dual union all
  3                        select to_date('01.01.2021','dd.mm.yyyy') date_from,
  4                               to_date('31.01.2021','dd.mm.yyyy') date_to from dual union all
  5                        select to_date('01.02.2021','dd.mm.yyyy') date_from,
  6                               to_date('28.02.2021','dd.mm.yyyy') date_to from dual union all
  7                        select to_date('01.03.2021','dd.mm.yyyy') date_from,
  8                               to_date('31.03.2021','dd.mm.yyyy') date_to from dual union all
  9                        select to_date('01.04.2021','dd.mm.yyyy') date_from,
 10                              to_date('30.04.2021','dd.mm.yyyy') date_to from dual),
 11           input   AS (select to_date('01.01.2021','dd.mm.yyyy') date_from, 1 c from dual union all
 12                       select to_date('01.03.2021','dd.mm.yyyy') date_from, 2 c from dual)
 13  select c.date_from, c.date_to, i.c
 14    ,last_value(i.c IGNORE NULLS) over (order by c.date_from) lv
 15  from calendar c, input i
 16  where c.date_from=i.date_from(+)
 17* order by c.date_from
SQL> /

DATE_FROM  DATE_TO             C         LV
---------- ---------- ---------- ----------
01.12.2020 31.12.2020
01.01.2021 31.01.2021          1          1
01.02.2021 28.02.2021                     1
01.03.2021 31.03.2021          2          2
01.04.2021 30.04.2021                     2

SQL>



ps
+ nvl если надо
.....
stax
...
Рейтинг: 0 / 0
01.07.2021, 21:50
    #40081262
AVP2012
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Размножить строки с переносом значения
всем спасибо большое за ответы! в приведенном примере действительно все хорошо, но немного усложнив, не получается

при добавлении первых двух строк в
Код: plsql
1.
2.
3.
4.
            input   AS select null date_from, 7 c from dual union all
                        select to_date('01.01.1990','dd.mm.yyyy') date_from, 11 c from dual union all
                        select to_date('01.01.2021','dd.mm.yyyy') date_from, 1 c from dual union all
                        select to_date('01.03.2021','dd.mm.yyyy') date_from, 2 c from dual)


хотелось бы, чтобы результат выглядел так

DATE_FROM DATE_TO C
----------- ----------- ----------
-- при null
01.12.2020 31.12.2020 7
01.01.2021 31.01.2021 7
01.02.2021 28.02.2021 7
01.03.2021 31.03.2021 7
01.04.2021 30.04.2021 7

--при дате меньше календаря
01.12.2020 31.12.2020 11
01.01.2021 31.01.2021 11
01.02.2021 28.02.2021 11
01.03.2021 31.03.2021 11
01.04.2021 30.04.2021 11

-- входят в период
01.12.2020 31.12.2020 0
01.01.2021 31.01.2021 1
01.02.2021 28.02.2021 1
01.03.2021 31.03.2021 2
01.04.2021 30.04.2021 2

возможно?

спасибо!
...
Рейтинг: 0 / 0
02.07.2021, 09:21
    #40081296
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Размножить строки с переносом значения
AVP2012

возможно?

в лоб
Код: 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.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
SQL> ed
Wrote file afiedt.buf

  1  WITH calendar AS (select to_date('01.12.2020','dd.mm.yyyy') date_from,
  2                                 to_date('31.12.2020','dd.mm.yyyy') date_to from dual union all
  3                          select to_date('01.01.2021','dd.mm.yyyy') date_from,
  4                                 to_date('31.01.2021','dd.mm.yyyy') date_to from dual union all
  5                          select to_date('01.02.2021','dd.mm.yyyy') date_from,
  6                                 to_date('28.02.2021','dd.mm.yyyy') date_to from dual union all
  7                          select to_date('01.03.2021','dd.mm.yyyy') date_from,
  8                                 to_date('31.03.2021','dd.mm.yyyy') date_to from dual union all
  9                          select to_date('01.04.2021','dd.mm.yyyy') date_from,
 10                                to_date('30.04.2021','dd.mm.yyyy') date_to from dual),
 11              input   AS (
 12                          select null date_from, 7 c from dual union all
 13                          select to_date('01.01.1990','dd.mm.yyyy') date_from, 11 c from dual union all
 14                          select to_date('01.01.2021','dd.mm.yyyy') date_from, 1 c from dual union all
 15                          select to_date('01.03.2021','dd.mm.yyyy') date_from, 2 c from dual)
 16  ,mi as (select nvl(min(date_from),to_date(1,'j')) min_i,min(c) KEEP (DENSE_RANK first ORDER BY date_from nulls first ) mc from input)
 17  ,mc as (select min(date_from) min_c from calendar)
 18  select c.date_from, c.date_to, i.c
 19      ,case when min_i>=min_c then nvl(last_value(i.c IGNORE NULLS) over (order by c.date_from),0)
 20                else mc end lv
 21    from calendar c, input i,mi,mc
 22    where c.date_from=i.date_from(+)
 23*  order by c.date_from
SQL> /

DATE_FROM  DATE_TO             C         LV
---------- ---------- ---------- ----------
01.12.2020 31.12.2020                     7
01.01.2021 31.01.2021          1          7
01.02.2021 28.02.2021                     7
01.03.2021 31.03.2021          2          7
01.04.2021 30.04.2021                     7

SQL> ed
Wrote file afiedt.buf

  1  WITH calendar AS (select to_date('01.12.2020','dd.mm.yyyy') date_from,
  2                                 to_date('31.12.2020','dd.mm.yyyy') date_to from dual union all
  3                          select to_date('01.01.2021','dd.mm.yyyy') date_from,
  4                                 to_date('31.01.2021','dd.mm.yyyy') date_to from dual union all
  5                          select to_date('01.02.2021','dd.mm.yyyy') date_from,
  6                                 to_date('28.02.2021','dd.mm.yyyy') date_to from dual union all
  7                          select to_date('01.03.2021','dd.mm.yyyy') date_from,
  8                                 to_date('31.03.2021','dd.mm.yyyy') date_to from dual union all
  9                          select to_date('01.04.2021','dd.mm.yyyy') date_from,
 10                                to_date('30.04.2021','dd.mm.yyyy') date_to from dual),
 11              input   AS (
 12  --                        select null date_from, 7 c from dual union all
 13                          select to_date('01.01.1990','dd.mm.yyyy') date_from, 11 c from dual union all
 14                          select to_date('01.01.2021','dd.mm.yyyy') date_from, 1 c from dual union all
 15                          select to_date('01.03.2021','dd.mm.yyyy') date_from, 2 c from dual)
 16  ,mi as (select nvl(min(date_from),to_date(1,'j')) min_i,min(c) KEEP (DENSE_RANK first ORDER BY date_from nulls first ) mc from input)
 17  ,mc as (select min(date_from) min_c from calendar)
 18  select c.date_from, c.date_to, i.c
 19      ,case when min_i>=min_c then nvl(last_value(i.c IGNORE NULLS) over (order by c.date_from),0)
 20                else mc end lv
 21    from calendar c, input i,mi,mc
 22    where c.date_from=i.date_from(+)
 23*  order by c.date_from
SQL> /

DATE_FROM  DATE_TO             C         LV
---------- ---------- ---------- ----------
01.12.2020 31.12.2020                    11
01.01.2021 31.01.2021          1         11
01.02.2021 28.02.2021                    11
01.03.2021 31.03.2021          2         11
01.04.2021 30.04.2021                    11

SQL> ed
Wrote file afiedt.buf

  1  WITH calendar AS (select to_date('01.12.2020','dd.mm.yyyy') date_from,
  2                                 to_date('31.12.2020','dd.mm.yyyy') date_to from dual union all
  3                          select to_date('01.01.2021','dd.mm.yyyy') date_from,
  4                                 to_date('31.01.2021','dd.mm.yyyy') date_to from dual union all
  5                          select to_date('01.02.2021','dd.mm.yyyy') date_from,
  6                                 to_date('28.02.2021','dd.mm.yyyy') date_to from dual union all
  7                          select to_date('01.03.2021','dd.mm.yyyy') date_from,
  8                                 to_date('31.03.2021','dd.mm.yyyy') date_to from dual union all
  9                          select to_date('01.04.2021','dd.mm.yyyy') date_from,
 10                                to_date('30.04.2021','dd.mm.yyyy') date_to from dual),
 11              input   AS (
 12  --                        select null date_from, 7 c from dual union all
 13  --                        select to_date('01.01.1990','dd.mm.yyyy') date_from, 11 c from dual union all
 14                          select to_date('01.01.2021','dd.mm.yyyy') date_from, 1 c from dual union all
 15                          select to_date('01.03.2021','dd.mm.yyyy') date_from, 2 c from dual)
 16  ,mi as (select nvl(min(date_from),to_date(1,'j')) min_i,min(c) KEEP (DENSE_RANK first ORDER BY date_from nulls first ) mc from input)
 17  ,mc as (select min(date_from) min_c from calendar)
 18  select c.date_from, c.date_to, i.c
 19      ,case when min_i>=min_c then nvl(last_value(i.c IGNORE NULLS) over (order by c.date_from),0)
 20                else mc end lv
 21    from calendar c, input i,mi,mc
 22    where c.date_from=i.date_from(+)
 23*  order by c.date_from
SQL> /

DATE_FROM  DATE_TO             C         LV
---------- ---------- ---------- ----------
01.12.2020 31.12.2020                     0
01.01.2021 31.01.2021          1          1
01.02.2021 28.02.2021                     1
01.03.2021 31.03.2021          2          2
01.04.2021 30.04.2021                     2

SQL>


.....
stax
...
Рейтинг: 0 / 0
02.07.2021, 12:07
    #40081345
AVP2012
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Размножить строки с переносом значения
прошу прощения, криво объяснил.
добавим некий идентификаторьв input,
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
WITH calendar AS (select to_date('01.12.2020','dd.mm.yyyy') date_from,
                             to_date('31.12.2020','dd.mm.yyyy') date_to from dual union all
                      select to_date('01.01.2021','dd.mm.yyyy') date_from,
                             to_date('31.01.2021','dd.mm.yyyy') date_to from dual union all
                      select to_date('01.02.2021','dd.mm.yyyy') date_from,
                             to_date('28.02.2021','dd.mm.yyyy') date_to from dual union all
                      select to_date('01.03.2021','dd.mm.yyyy') date_from,
                             to_date('31.03.2021','dd.mm.yyyy') date_to from dual union all
                      select to_date('01.04.2021','dd.mm.yyyy') date_from,
                            to_date('30.04.2021','dd.mm.yyyy') date_to from dual),
            input   AS (select 111 id, null date_from, 7 c from dual union all
                        select 222 id, to_date('01.01.1990','dd.mm.yyyy') date_from, 11 c from dual union all
                        select 333 id, to_date('01.01.2021','dd.mm.yyyy') date_from, 1 c from dual union all
                        select 333 id, to_date('01.03.2021','dd.mm.yyyy') date_from, 2 c from dual)
   select i.id, c.date_from, c.date_to, i.c from calendar c, input i
   order by c.date_from



вот что хотелось бы в результате:
ID DATE_FROM DATE_TO C
----------- ----------- ----------- ----------
111 01.12.2020 31.12.2020 7
111 01.01.2021 31.01.2021 7
111 01.02.2021 28.02.2021 7
111 01.03.2021 31.03.2021 7
111 01.04.2021 30.04.2021 7
222 01.12.2020 31.12.2020 11
222 01.01.2021 31.01.2021 11
222 01.02.2021 28.02.2021 11
222 01.03.2021 31.03.2021 11
222 01.04.2021 30.04.2021 11
333 01.12.2020 31.12.2020 0
333 01.01.2021 31.01.2021 1
333 01.02.2021 28.02.2021 1
333 01.03.2021 31.03.2021 2
333 01.04.2021 30.04.2021 2

никак не совладаю с 333, декартово размножает на N строк, как провести связку периодов не пойму, чтобы только на количество строк в календаре, в данном случае, на каждый id только 5 строк :\
...
Рейтинг: 0 / 0
02.07.2021, 12:38
    #40081362
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Размножить строки с переносом значения
AVP2012

вот что хотелось бы в результате:


самое простое(не оптимальное)
111+222
union all
333

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


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