powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Связывание внутренних селектов друг с другом
5 сообщений из 5, страница 1 из 1
Связывание внутренних селектов друг с другом
    #40093500
verter
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Использую Oracle 12

Имеются 3 таблицы: SOURCE_TBL, DEST_TBL, MAIN_TBL

Из таблиц SOURCE_TBL и MAIN_TBL делается выборка, которая записывается в DEST_TBL

Из таблицы SOURCE_TBL в цикле выбираются данные следующего типа:

Код: sql
1.
2.
3.
4.
num  start_date    end_date
1      01.01.2021   05.01.2021
2      03.02.2021   09.02.2021
.........................................


т.е. на 1 num всего 1 запись с начальной и конечной датой (это задаёт диапазон)

В таблице MAIN_TBL содержаться данные следующего вида:

Код: sql
1.
2.
3.
4.
5.
6.
7.
num  out_date       val1
1      01.01.2021    11
1      02.01.2021    12
1      05.01.2021    13
2      04.02.2021    21
2      05.02.2021    22 
2      07.02.2021    23


т.е. в диапазоне для num=1 в out_date имеются дырки: 03.01.2021, 04.01.2021
для num=2 тоже есть дырки: 03.02.2021, 06.02.2021, 08.02.2021, 09.02.2021

Необходимо из MAIN_TBL вывести значения с учётом каждой даты в диапазоне, т.е. должно быть так:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
num  cur_date      val1
1       01.01.2021  11
1       02.01.2021  12
1       03.01.2021    0
1       04.01.2021    0
1       04.01.2021  13
2       03.02.2021    0
2       04.02.2021  21
2       05.02.2021  22
2       06.02.2021    0
2       07.02.2021  23
2       08.02.2021    0
2       09.02.2021    0


Для того чтобы такое сделать я внутренним запросом (p2) получаю для каждого num таблицу дат в указанном в SOURCE_TBL диапазоне. Но приходится делать цикл, чтобы начальную и конечную дату передавать в этот внутренний запрос p2

т.к. используется цикл, то работает очень медленно. Подскажите знатоки как бы так всё это переписать одним селектом чтобы не нужно было использовать цикл?

Вот этот работающий медленный вариант:

Код: sql
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.
begin
   for i in (
              select num,
                       start_date,
                       end_date
              from SOURCE_TBL
            )
  loop
    insert into DEST_TBL (
    ...............
    )
    select t.num,
             p2.cur_date,
             t.val1,
             .................
    from (
             -- даёт диапазон дат в виде таблицы 
             select p1.s + level as cur_date
             from (
                     select p.*, p.e - p.s as dif 
                     from ( 
                             select i.end_date as e, 
                                      i.start_date as s 
                             from dual
                            ) p
                    ) p1     
             connect by level <= p1.dif
             -------------------------------------------
            ) p2, 
            MAIN_TBL t
    where t.num = i.num
       and p2.cur_date = t.out_date (+)
    ;
  end loop;            
end;
...
Рейтинг: 0 / 0
Связывание внутренних селектов друг с другом
    #40093502
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
verter,

для
1 01.01.2021 05.01.2021
2 03.02.2021 09.02.2021

сгенерить дни из диапазона
(помоему SY разные методы приводил)
и соеденить с main

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

так я и генерирую их вот так:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select p1.s + level as cur_date
from (
         select p.*, p.e - p.s as dif 
          from ( 
                   select i.end_date as e, 
                            i.start_date as s 
                   from dual
                  ) p
        ) p1     
connect by level <= p1.dif
...
Рейтинг: 0 / 0
Связывание внутренних селектов друг с другом
    #40093506
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
verter
Stax,

так я и генерирую их вот так:



сгенерить за раз для всех num

ps
попробовать генерить другим методом

pss
если pl/sql и с циклом
for i in (select num,start_date,end_date from SOURCE_TBL
не соеденять таблицы, а осложнить алгоритм вставки

if dat=prev dat-1 then
else

...

.....
stax
...
Рейтинг: 0 / 0
Связывание внутренних селектов друг с другом
    #40093770
DymSig
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
verter,
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
WITH A AS (
            SELECT DATE '2021-01-01' AS START_DATE, DATE '2021-01-05' AS END_DATE FROM DUAL
            UNION ALL
            SELECT DATE '2021-02-03' AS START_DATE, DATE '2021-02-09' AS END_DATE FROM DUAL
            )    
   , B AS ( 
            SELECT  START_DATE, END_DATE - START_DATE  + 1 AS DELTA FROM A 
            ) 
SELECT  START_DATE - 1 + ROW_NUMBER() OVER (PARTITION BY START_DATE ORDER BY NULL) AS DAILY
FROM B
CROSS JOIN TABLE(SELECT CAST(COLLECT(1) AS SYS.ODCINUMBERLIST) FROM DUAL CONNECT BY LEVEL <= B.DELTA) T 
; 
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Связывание внутренних селектов друг с другом
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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