Да тут много разных вариантов может быть, смотря какую задачу решать. Но принцип все равно останется тот же: вначале сформировать последовательность, потом с ней соединить имеющиеся данные.
Модельки как раз работают после получения данных.
Для разовых задач наверное проще использовать голый SQL типа иерархического, для часто повторяющихся лучше создать функцию.
Функция практически всегда будет медленнее, а если еще и не пайплайн, то и память отжирать.
CREATE OR REPLACE FUNCTION Generate_Date_Sequence( -- Генератор посл-ти дат.
Data_Beg DATE, /*Начальная дата.*/
Data_End DATE, /*Конечная дата.*/
Step CHAR) /*Шаг в последовательности дат: D - день, M - месяц, Y - год.*/
RETURN TDate_Sequence
AS
data_curr DATE;
stp CHAR:= UPPER(Step);
Result TDate_Sequence := TDate_Sequence();
BEGIN
data_curr := TRUNC( Data_Beg,
case stp
when 'D' then 'DD'
when 'M' then 'MM'
when 'Y' then 'YYYY'
end);
-- Сформировать последовательность дат.
WHILE data_curr <= Data_End LOOP
Result.EXTEND;
Result(Result.LAST) := data_curr;
case stp
when 'D' then data_curr := data_curr + 1;
when 'M' then data_curr := ADD_MONTHS(data_curr, 1);
when 'Y' then data_curr := ADD_MONTHS(data_curr, 12);
end case;
END LOOP;
-- Вернуть результат.
RETURN Result;
END Generate_Date_Sequence;
Еще вариант динамического генератора:
Получаем динамически необходимое кол-во дублированных строк(N штук для каждой строки)
with t as (
select 1 n,trunc(sysdate-5) dt from dual union all
select 2 n,trunc(sysdate-3) dt from dual union all
select 3 n,trunc(sysdate-1) dt from dual
)
select
n
,generator.column_value
,dt+generator.column_value
from
t
,table(cast(multiset(select level from dual connect by level<=t.n) as sys.odcinumberlist)) generator
Как-то грустно совсем… Даже сравнивать не хочется с теми решениями, что были на других языках. Явно не гольфить против perl и ruby.(golfscript не считаю интересным)
Ну формулировка то есть — причина описана, а результат я не вывел потому что хотел дать код удобный для копирования и выполнения, но раз хотите, то добавлю и вывод
Number precision too large? :) можно, конечно, это нарочно сэмулировать — создать в этой схеме свой такой пакет с этой функцией и в нем вызвать ошибку, но это было бы очень странно.
Пример: www.xt-r.com/2010/11/oracle-svn-git-etc.html
Модельки как раз работают после получения данных.
Функция практически всегда будет медленнее, а если еще и не пайплайн, то и память отжирать.
Освещать сейчас банальные решения о 8i сейчас? Вы смеетесь? Давайте тогда еще пуд всяких FAQ'ов для всех версий старей 10 лет сюда перепишем?
CREATE OR REPLACE FUNCTION Generate_Date_Sequence( -- Генератор посл-ти дат. Data_Beg DATE, /*Начальная дата.*/ Data_End DATE, /*Конечная дата.*/ Step CHAR) /*Шаг в последовательности дат: D - день, M - месяц, Y - год.*/ RETURN TDate_Sequence AS data_curr DATE; stp CHAR:= UPPER(Step); Result TDate_Sequence := TDate_Sequence(); BEGIN data_curr := TRUNC( Data_Beg, case stp when 'D' then 'DD' when 'M' then 'MM' when 'Y' then 'YYYY' end); -- Сформировать последовательность дат. WHILE data_curr <= Data_End LOOP Result.EXTEND; Result(Result.LAST) := data_curr; case stp when 'D' then data_curr := data_curr + 1; when 'M' then data_curr := ADD_MONTHS(data_curr, 1); when 'Y' then data_curr := ADD_MONTHS(data_curr, 12); end case; END LOOP; -- Вернуть результат. RETURN Result; END Generate_Date_Sequence;Получаем динамически необходимое кол-во дублированных строк(N штук для каждой строки)
with t as ( select 1 n,trunc(sysdate-5) dt from dual union all select 2 n,trunc(sysdate-3) dt from dual union all select 3 n,trunc(sysdate-1) dt from dual ) select n ,generator.column_value ,dt+generator.column_value from t ,table(cast(multiset(select level from dual connect by level<=t.n) as sys.odcinumberlist)) generator