создать новые строки, используя два столбца даты и повторяя значение суммы - PullRequest
1 голос
/ 14 апреля 2020

Имея эту настройку:

CREATE SEQUENCE  "SEQ_TABLE_3"  MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 2206 NOCACHE  ORDER  NOCYCLE  NOKEEP  NOSCALE  GLOBAL ;

CREATE TABLE TABLE_3 ( 
     ID NUMBER DEFAULT SEQ_TABLE_3.nextval  NOT NULL
    ,DATE_INI   DATE NOT NULL
    ,DATE_FIN   DATE NOT NULL
    ,ELEMENTS   NUMBER
);


Insert into TABLE_3 (DATE_INI,DATE_FIN,ELEMENTS) values (to_date('19/04/01','RR/MM/DD'),to_date('19/04/10','RR/MM/DD'),3);
Insert into TABLE_3 (DATE_INI,DATE_FIN,ELEMENTS) values (to_date('19/04/01','RR/MM/DD'),to_date('19/04/10','RR/MM/DD'),2);
Insert into TABLE_3 (DATE_INI,DATE_FIN,ELEMENTS) values (to_date('19/04/01','RR/MM/DD'),to_date('19/04/10','RR/MM/DD'),1);
Insert into TABLE_3 (DATE_INI,DATE_FIN,ELEMENTS) values (to_date('19/04/01','RR/MM/DD'),to_date('19/04/10','RR/MM/DD'),5);
Insert into TABLE_3 (DATE_INI,DATE_FIN,ELEMENTS) values (to_date('19/04/01','RR/MM/DD'),to_date('19/04/10','RR/MM/DD'),4);
Insert into TABLE_3 (DATE_INI,DATE_FIN,ELEMENTS) values (to_date('19/04/01','RR/MM/DD'),to_date('19/04/10','RR/MM/DD'),6);
Insert into TABLE_3 (DATE_INI,DATE_FIN,ELEMENTS) values (to_date('19/04/01','RR/MM/DD'),to_date('19/04/10','RR/MM/DD'),9);
Insert into TABLE_3 (DATE_INI,DATE_FIN,ELEMENTS) values (to_date('19/04/01','RR/MM/DD'),to_date('19/04/10','RR/MM/DD'),1);
Insert into TABLE_3 (DATE_INI,DATE_FIN,ELEMENTS) values (to_date('19/04/01','RR/MM/DD'),to_date('19/04/10','RR/MM/DD'),2);
Insert into TABLE_3 (DATE_INI,DATE_FIN,ELEMENTS) values (to_date('19/04/01','RR/MM/DD'),to_date('19/04/10','RR/MM/DD'),4);
Insert into TABLE_3 (DATE_INI,DATE_FIN,ELEMENTS) values (to_date('19/04/01','RR/MM/DD'),to_date('19/04/10','RR/MM/DD'),5);
Insert into TABLE_3 (DATE_INI,DATE_FIN,ELEMENTS) values (to_date('19/04/01','RR/MM/DD'),to_date('19/04/10','RR/MM/DD'),6);
Insert into TABLE_3 (DATE_INI,DATE_FIN,ELEMENTS) values (to_date('19/04/01','RR/MM/DD'),to_date('19/04/10','RR/MM/DD'),2);
Insert into TABLE_3 (DATE_INI,DATE_FIN,ELEMENTS) values (to_date('19/04/01','RR/MM/DD'),to_date('19/04/10','RR/MM/DD'),7);
commit;

Я пытаюсь получить этот результат:

enter image description here

Идея заключается в имея date_ini и date_fin, воссоздайте строки со значениями даты, которые будут между date_ini и date_fin и суммой всех elements. Если честно, я не знаю с чего начать

Ответы [ 2 ]

2 голосов
/ 14 апреля 2020

Это можно сделать с помощью рекурсивного запроса:

with cte(dates, date_ini, date_fin, sum_elements) as (
    select date_ini dates, date_ini, date_fin, sum(elements) sum_elements 
    from table_3
    group by date_ini, date_fin
    union all
    select dates + 1, date_ini, date_fin, sum_elements
    from cte
    where dates < date_fin
)
select * from cte

Демонстрация на DB Fiddle :

DATES     | DATE_INI  | DATE_FIN  | SUM_ELEMENTS
:-------- | :-------- | :-------- | -----------:
01-APR-19 | 01-APR-19 | 10-APR-19 |           57
02-APR-19 | 01-APR-19 | 10-APR-19 |           57
03-APR-19 | 01-APR-19 | 10-APR-19 |           57
04-APR-19 | 01-APR-19 | 10-APR-19 |           57
05-APR-19 | 01-APR-19 | 10-APR-19 |           57
06-APR-19 | 01-APR-19 | 10-APR-19 |           57
07-APR-19 | 01-APR-19 | 10-APR-19 |           57
08-APR-19 | 01-APR-19 | 10-APR-19 |           57
09-APR-19 | 01-APR-19 | 10-APR-19 |           57
10-APR-19 | 01-APR-19 | 10-APR-19 |           57
0 голосов
/ 14 апреля 2020

То же самое можно сделать только с помощью рефакторинга подзапроса, как показано ниже.

DEMO здесь

        WITH data
         AS (SELECT date_ini + column_value - 1 AS dates,
                    date_ini,
                    date_fin,
                    elements
             FROM   table_3
                    cross join TABLE(Cast(MULTISET (SELECT LEVEL
                                              FROM   dual
                                              CONNECT BY date_ini + LEVEL <=
                                                         date_fin + 1
                                                   )
                                          AS
         sys.ODCINUMBERLIST)))
    SELECT dates,
           date_ini,
           date_fin,
           SUM(elements)
    FROM   data
    GROUP  BY dates,
              date_ini,
              date_fin
    ORDER  BY dates,
              date_ini,
              date_fin; 
...