Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2008.09.14;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.059 c
15-1216798715
axis_of_evil
2008-07-23 11:38
2008.09.14
на моей памяти этот вопрос задавали раз 5, но ..


2-1217390260
apic
2008-07-30 07:57
2008.09.14
сокрытие файлов и папок


15-1216271482
Dennis I. Komarov
2008-07-17 09:11
2008.09.14
MS WinXP SP3


15-1216815562
oldman
2008-07-23 16:19
2008.09.14
А у меня завтра дочери исполняется шесть лет!


2-1217575300
DeeNamid
2008-08-01 11:21
2008.09.14
Пинг





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский