Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.09.14;
Скачать: CL | DM;

Вниз

Оракл : достать вычисленное поле из предыдущей записи   Найти похожие ветки 

 
ANB   (2008-03-19 10:43) [0]

Имеем (тестовая таблица, реал чуток сложнее) :
create table Test1
(
 ID integer,
 Group_ID integer,
 F1 number,
 F2 number,
 F3 number
)
/
Insert into Test1
  (ID, GROUP_ID, F1, F2, F3)
Values
  (1, 1, 1, 1, 0)
/  
Insert into Test1
  (ID, GROUP_ID, F1, F2, F3)
Values
  (2, 1, 2, 1, 2)
/  
Insert into Test1
  (ID, GROUP_ID, F1, F2, F3)
Values
  (3, 1, 1, 2, 1)
/  
Insert into Test1
  (ID, GROUP_ID, F1, F2, F3)
Values
  (4, 1, 2, 2, 16)
/  
Insert into Test1
  (ID, GROUP_ID, F1, F2, F3)
Values
  (5, 1, 1, 2, 1)
/  
Insert into Test1
  (ID, GROUP_ID, F1, F2, F3)
Values
  (6, 1, 2, 2, 3)
/  
Insert into Test1
  (ID, GROUP_ID, F1, F2, F3)
Values
  (7, 1, 2, 2, 2)
/  
Insert into Test1
  (ID, GROUP_ID, F1, F2, F3)
Values
  (8, 1, 2, 2, 5)
/  
COMMIT
/

-- Скрипт :
declare
 v_Over_Sum number;
 v_Over number;
begin
 dbms_output.enable(1000000);
 v_Over_Sum := 0;
 for R in (select T.* from Test1 T order by ID)
 loop
   v_Over := R.F1 + R.F2 + v_Over_Sum - R.F3;
   if v_Over > 0 then
  v_Over_Sum := v_Over_Sum + v_Over;
else
  v_Over_Sum := 0;
end if;
dbms_output.put_line(R.ID||". v_Over = "||v_Over||", v_Over_Sum = "||v_Over_Sum);
 end loop;
end;

Надо : вытащить тоже самое, что делает скрипт, запросом.
Типа
select T.*, 0 f_Over, 0 f_OverSum from Test1 T order by T.ID
есно, вместо нулей подставить выражения.

Что делал : перекопал всю аналитику, но эти функции не умеют доставать вычисленное поле, тока из таблицы.


 
Johnmen ©   (2008-03-19 11:43) [1]

Что такое "вычисленное поле"?

PS
Думается, что здесь ошибка:

> v_Over := R.F1 + R.F2 + v_Over_Sum - R.F3;     
> if v_Over > 0 then   v_Over_Sum := v_Over_Sum + v_Over;


 
ANB   (2008-03-19 12:10) [2]


> Johnmen ©   (19.03.08 11:43) [1]

Нету там ошибки. Код фактически содран из реальной хранимки.
Описания и ТЗ нету, т.е. пока стоит задача ускорить, сохранив функционал.
Утвержается, что существующий алгоритм работает правильно (только очень долго). Нашел, что можно в нем оптимизнуть, но это даст прирос скорости процентов на 10. А надо - в 8 раз ускорить. Это только переводом на запросы можно сделать.

Вычисленное поле - v_Over_Sum. Я мог бы считать его на лету, обращаясь к предыдущей записи за предыдущим значением, но аналитическая функция его не видет.

вся загвоздка в
else
 v_Over_Sum := 0;
end if;
Иначе все было бы намного проще : я уже и формулу вывел и SQL накопительные суммы без проблем считает. А вот зануление все режет - надо делать case, а потом ссылаться на него. и все. приехали.


 
Johnmen ©   (2008-03-19 12:30) [3]


> ANB   (19.03.08 12:10) [2]

1. Если я правильно понял по сути, что надо, то ответ - никак.
2. Если бы вдруг можно было бы, то сомневаюсь в сколь-нибудь существенном приращении скорости.
3. По поводу предполагаемой ошибки: какой логическо-математический смысл удваивать сумму на каждой итерации?


 
ANB   (2008-03-19 12:56) [4]


> какой логическо-математический смысл удваивать сумму на
> каждой итерации?

Да не удваивается сумма. Я проверял работу скрипта. Все верно. Это не удваивание, а учет накопившихся недоплат.


> то сомневаюсь в сколь-нибудь существенном приращении скорости.

Проверяли. По индексу нестед лупс - 20 часов. Фулл скан с хэш джойном - 1.5 часа.
А тут мало того, что по индексу идет, так еще и для каждой записи явно хранимка вызывается с примерно таким скриптом. Т.е. совсем тяжкий вариант. Но прежде чем оптимизить планы, надо от хранимки избавится. Милин.


 
Johnmen ©   (2008-03-19 13:08) [5]


> Да не удваивается сумма.

Имелось в виду
v_Over_Sum=v_Over_Sum + v_Over
=v_Over_Sum+R.F1+R.F2+v_Over_Sum-R.F3
=2*v_Over_Sum+R.F1+R.F2-R.F3
Ну раз все верно, то и ладно...

> Проверяли.

Если проверяли, то, наверное, сделали. Тогда к чему вопрос [0]?


 
ANB   (2008-03-19 13:19) [6]

А. Точно. Вот так должно быть :

declare
 v_Over_Sum number;
 v_Over number;
begin
 dbms_output.enable(1000000);
 v_Over_Sum := 0;
 for R in (select T.* from Test1 T order by ID)
 loop
   v_Over := R.F1 + R.F2 + v_Over_Sum - R.F3;
   if v_Over > 0 then
  v_Over_Sum := v_Over_Sum + R.F1 + R.F2 - R.F3;
else
  v_Over_Sum := 0;
end if;
dbms_output.put_line(R.ID||". v_Over = "||v_Over||", v_Over_Sum = "||v_Over_Sum);
 end loop;
end;


 
Игорь Шевченко ©   (2008-03-19 14:25) [7]

ANB   (19.03.08 13:19) [6]

Вроде написано понятно. А со всякими CASE и аналитикой вся понятность может уйти. Я бы так оставил :)


 
Sergey13 ©   (2008-03-19 14:46) [8]

> [2] ANB   (19.03.08 12:10)
> вся загвоздка в
> else
> v_Over_Sum := 0;
> end if;

Так может на клиенте это проще прогнать?


 
ANB   (2008-03-19 14:50) [9]


> А со всякими CASE и аналитикой вся понятность может уйти.
>  Я бы так оставил :)

Медленно.

> Так может на клиенте это проще прогнать?

Еще медленнее, т.к. добавится траффик сервер - клиент.

Ответ на SQL.ru мне дали, тока под 10. А у меня 9-ка :(


 
Игорь Шевченко ©   (2008-03-19 15:01) [10]

ANB   (19.03.08 14:50) [9]


> Ответ на SQL.ru мне дали, тока под 10


MODEL что ли ?

А покажи ответ (точнее ссылку)


 
^-k2-^ ©   (2008-03-19 15:02) [11]

http://www.sql.ru/forum/actualthread.aspx?tid=537562


 
Игорь Шевченко ©   (2008-03-19 15:09) [12]

^-k2-^ ©   (19.03.08 15:02) [11]

Ну факт модель



Страницы: 1 вся ветка

Текущий архив: 2008.09.14;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.03 c
15-1216887249
No_Dead (w)
2008-07-24 12:14
2008.09.14
Никто не пробовал?


2-1217456314
Dars73
2008-07-31 02:18
2008.09.14
Неполучается создать таблицу


15-1216304096
Nous Mellon_
2008-07-17 18:14
2008.09.14
Вопрос по пхп. Снова


15-1216883567
ееееееекенитен
2008-07-24 11:12
2008.09.14
можно ли подключить к ноуту 2 одновоременно работающих WiFi-устр?


15-1216701537
Sergey13
2008-07-22 08:38
2008.09.14
СУБД Ред База Данных. Никто не пробовал? Как впечатления?