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

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


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

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


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