Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Есть историяот даты - надо историю на каждую дату  [new]
Быков Игорь Викторович
Member

Откуда:
Сообщений: 61
есть история изменения остатка на даты когда он реально изменялся. база здоровая. (монстр)
а нужно база остатка на каждый день даже когда не менялся. притом виртуальная так смысла в монстре в квадрате нет, реально будут брать период, или детализацию обьекта

попытка соеденить это с обьеденение базой где все даты приводит к огромным планам. и времени выполнения.

решил делать на функции pipeline. но там вопрос функцию я то сделаю - будет эта таблица. как сделать чтобы условие на эту
пипе таблицу проваливалось к исходной. (они одинаковы)

select * from pipetab( select * from монстрмаленький) where d>.. and  d<.. and cliet=..

(так как сам селект строю не я, а система IBSO а она построит только
 select * from view  where d>.. and  d<.. and cliet=..


если нет. то нет ли других способов в оракле. иррархия, аналитика, cube. а не только умножения исходника на все даты.

если будет стандартная то хоть и медление, но внешние условия провалятся вниз.


задача в принципи для отчетов частая. может кто уже делал, с полным сознанием дела.
9 фев 12, 06:13    [12059126]     Ответить | Цитировать Сообщить модератору
 Re: Есть историяот даты - надо историю на каждую дату  [new]
Добрый Э - Эх
Guest
Выбрал ты из таблицы нужные данные за интересующий тебя интервал времени. Сколько строк получается в этом наборе? Неужто так много, что соединение со списком дат дает неподъемные для Оракла объемы данных?
9 фев 12, 07:49    [12059175]     Ответить | Цитировать Сообщить модератору
 Re: Есть историяот даты - надо историю на каждую дату  [new]
Быков Игорь Викторович
Member

Откуда:
Сообщений: 61
Добрый Э - Эх
Выбрал ты из таблицы нужные данные за интересующий тебя интервал времени. Сколько строк получается в этом наборе? Неужто так много, что соединение со списком дат дает неподъемные для Оракла объемы данных?


Ну сейчас 3 милиона, полный интервал 30, когда 3 милиона сделал на каждую дату получил 30, работало долго.
если возму полный диапазон то лучше застрелится и не мучится.

просто ведь задача,по существу тривиальная, если нет на дату строки, просто повтори предыдущию, ну только поле даты измени на дату где нет строки. как бы выборка, с генерацией виртуальных строк.

т.е. по хорошему, прочитал 3 милиона выдал 30 но за времяпочти не более 3 так как эти виртуальные 27 уже есть в памяти и уходят в память, ну раза 3-5. а при соеденении получается, чето существенно больше, фул скан 3 милионов несопоаставим с получение 3 на 10.

но впринцепе уже решил, бизнес добавил условие, интервал дат, и выбор 1 клиента, сделаю пайп, над кусором куда контекстом провалю даты и клиента.

пайп четко делает размножение. ( поначалу я думал, а как, при пайпе провалить, туда всю кучу многочисленных условий, но незнаю,работа в среде IBSO, както не способтвует, знанию оракла. в совершенстве.
9 фев 12, 11:51    [12060583]     Ответить | Цитировать Сообщить модератору
 Re: Есть историяот даты - надо историю на каждую дату  [new]
Добрый Э - Эх
Guest
Если есть подходящие индексы в таблице , то...

1) генерируешь нужный диапазон дат (месяц - всего 28-31 строк)
2) в селект-листе запроса-датогенератора лезешь в таблицу с остатками и при помощи KEEP FIRST/LAST получаешь значение остатка на требуемую дату.
9 фев 12, 12:38    [12061104]     Ответить | Цитировать Сообщить модератору
 Re: Есть историяот даты - надо историю на каждую дату  [new]
Dimka08
Member

Откуда:
Сообщений: 319
Быков Игорь Викторович
есть история изменения остатка на даты когда он реально изменялся. база здоровая. (монстр)
а нужно база остатка на каждый день даже когда не менялся. притом виртуальная так смысла в монстре в квадрате нет, реально будут брать период, или детализацию обьекта

Используйте left outer join к запросу, возращающему все даты за нужный период, и lag( ignore nulls), предварительно посчитав все остатки на первую дату периода.
Но по моему опыту лучше сделать еще одну таблицу с остатками на каждую дату.
9 фев 12, 14:01    [12062112]     Ответить | Цитировать Сообщить модератору
 Re: Есть историяот даты - надо историю на каждую дату  [new]
ДохтаР
Member [заблокирован]

Откуда: Новоукраинск
Сообщений: 16864
В первом приближении задачу должен решить left outer join с коррелированным подзапросом.

Очень приблизительно так :
select 
....
dd1.date ,
when  bh1.clent is null  --  изменений  на дату из    dic_date нет
then  select balance from   bill_history bh2    where  
change_id = ( select max(change_id)  from  bill_history bh3 -- максимальный  change_id за дату меньше  dd1.date
where  bh3.change_date  < dd1.date   )
......

from  dic_date  dd1  left outer join  bill_history bh1 
                                       on dd1.date = bh1. change_date 
                                left outer join  client_bill cb1   
                                       on cb1.cliet=bh1.clent
 where cb1.client= .....
and    ...  условие   диапазона     дат


ps
9 фев 12, 15:59    [12063643]     Ответить | Цитировать Сообщить модератору
 Re: Есть историяот даты - надо историю на каждую дату  [new]
ДохтаР
Member [заблокирован]

Откуда: Новоукраинск
Сообщений: 16864
ДохтаР
В первом приближении задачу должен решить left outer join с коррелированным подзапросом.

Очень приблизительно так :
select 
....
dd1.date ,
when  bh1.clent is null  --  изменений  на дату из    dic_date нет
then  select balance from   bill_history bh2    where  
change_id = ( select max(change_id)  from  bill_history bh3 -- максимальный  change_id за дату меньше  dd1.date
where  bh3.change_date  < dd1.date  
and cb1.client=bh3.client  -- в первой версии упустил  привязку к  клиенту
)
......

from  dic_date  dd1  left outer join  bill_history bh1 
                                       on dd1.date = bh1. change_date 
                                left outer join  client_bill cb1   
                                       on cb1.cliet=bh1.clent
 where cb1.client= .....
and    ...  условие   диапазона     дат


ps
9 фев 12, 16:42    [12064148]     Ответить | Цитировать Сообщить модератору
 Re: Есть историяот даты - надо историю на каждую дату  [new]
Быков Игорь Викторович
Member

Откуда:
Сообщений: 61
ДохтаР,

спасибо. советы помогли.
сделал просто копию этой барахолки на каждую дату. отчеты будут ее трепать.

пипелайн тоже сделаем посмотрим как они, будут ли летать.

по прошлому применению pipelined они мне сильно понравились. и созданием виртуальный таблиц.

и для условия where - как бы получилась параметризованная вьюха, от условий кто зашел что хочет, полный список выдовал разные наборы данных. и шустро работала.
9 фев 12, 18:37    [12065227]     Ответить | Цитировать Сообщить модератору
 Re: Есть историяот даты - надо историю на каждую дату  [new]
Быков Игорь Викторович
Member

Откуда:
Сообщений: 61
добавили валюту и счет и все поплыло. пришлось перейти на конвейрные функции. очень удачно.
для тех кто захочет воспользоватся примерный вид.

cursor ost1(DN date,DK date,pcln number,ps number,pbo varchar2,pbc varchar2,pval number) is
SELECT cln,s,bo,bc,val,dat,ost,ostk  FROM a_y_ost where cln=pcln and s=ps and bo=pbo and bc=pbc and val=pval and dat>DN and dat<DK order by dat;

cursor md1(DN date,pcln number,ps number,pbo varchar2,pbc varchar2,pval number) is
SELECT dat,ost,ostk FROM a_y_ost where cln=pcln  and s=ps  and bo=pbo  and bc=pbc  and val=pval  and dat<=DN order by dat desc;

cursor mcl(pcln number) is
SELECT cln,s,bo,bc,val FROM a_y_ost a where cln=pcln group by cln,s,bo,bc,val order by cln,s,bo,bc,val;

function get_ost1(DN date,DK date,cln number)  return tab_yprost1 pipelined;


mcl кусор по всем сутям которые буду дублировать md1 срез на начало. ost1 таблице изменений остатка.

и сама функция которая делает таблицу на каждую божию дату. весьма быстро и без умножений. и на диске ее нет, но для работы какбы есть.


function copy_1(a mcl%rowtype,p_dat DATE, p_ost number, p_ostk number) return ypr_ost is begin
return ypr_ost(a.s,a.bo,a.bc,a.cln,a.val, p_dat, p_ost, p_ostk);
end;


function get_ost1(DN date,DK date,cln number) return tab_yprost1 pipelined is
zt ost1%rowtype;
c mcl%rowtype;
b  ypr_ost;
dt date;
ostt  number;
ostkt number;
kurs  number;
dkurs  date :=nvl(to_date(SYS_CONTEXT('IBS_USER','Y_OST_DKUR'),'DDMMYYYY'),trunc(sysdate,'MM') );
begin
  IF mcl%isopen  then  close mcl; end if;
  IF ost1%isopen then  close ost1; end if;


  for c in mcl(cln) loop

    for x in md1(dn,c.cln,c.s,c.bo,c.bc,c.val) loop
      dt:=dn;kurs:=get_kurs(dkurs,c.val);ostt:=kurs*x.ost;ostkt:=kurs*x.ostk; exit;
    end loop;

    for zt in  ost1(dn,dk,c.cln,c.s,c.bo,c.bc,c.val)  loop
        while dt<zt.dat loop
          b:=copy_1(c,dt,ostt,ostkt);
          pipe row(b);
          dt:=dt+1;
        end loop;
      ostt:=kurs*zt.ost;ostkt:=kurs*zt.ostk;
    end loop;

    while dt<dk loop
        b:=copy_1(c,dt,ostt,ostkt);
        pipe row(b);
        dt:=dt+1;
    end loop;

  end loop;
  return;
end;
16 фев 12, 09:55    [12100648]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить