Текущий архив: 2009.10.11;
Скачать: CL | DM;
Вниз
Помогите оптимизировать запрос (D2007, BDE, Paradox) Найти похожие ветки
← →
petvv (2008-11-28 09:25) [0]В общем есть такой код:
procedure TMainForm.GetCena;
begin
Cena.Active:=False;
Cena.SQL.Clear;
Cena.SQL.Add("select price from Statist where Statist.DateTime<:QDBeg and Statist.Product="+IntToStr(Temp.FieldByName("Product").Value) +" and Statist.Osnovanye=0");
Cena.ParamByName("QDBeg").AsDateTime:=Temp.FieldByName("DateTime").Value;
Cena.Active:=True;
Cena.RecordCount;
Cena.FindLast;
Cena1:=Cena.FieldByName("Price").Value;
Cena.Close;
end;
procedure TMainForm.btnStartClick(Sender: TObject);
begin
DT;
if DEnd<DBeg then
begin
MessageBox(0,"Дата окончания периода меньше даты начала периода !","Неверныё период расчётов",0);
Exit;
end;
qOsn.Close;
qOsn.Params[0].AsDateTime:=DBeg;
qOsn.Params[1].AsDateTime:=DEnd;
qOsn.Active:=True;
//********************************
Temp.Active:=False;
Temp.DataBaseName:="STATION32";
Temp.TableName:="Temp";
Temp.TableType:=ttParadox;
Temp.FieldDefs.Clear;
Temp.FieldDefs.Add("DateTime",ftDateTime);
Temp.FieldDefs.Add("Marka",ftString,50,False);
Temp.FieldDefs.Add("Product",ftFloat,0,False);
Temp.FieldDefs.Add("Osnovan",ftString,50,False);
Temp.FieldDefs.Add("Osnovanye",ftFloat,0,False);
Temp.FieldDefs.Add("Litr",ftFloat,0,False);
Temp.FieldDefs.Add("Summa",ftFloat,0,False);
Temp.FieldDefs.Add("Price",ftFloat,0,False);
Temp.FieldDefs.Add("Delta",ftFloat,0,False);
Temp.FieldDefs.Add("Report",ftBoolean,0,False);
Temp.FieldDefs.Add("Discount",ftBoolean,0,False);
Temp.CreateTable;
Temp.Active:=True;
Temp.Edit;
Temp.First;
for n:=1 to qOsn.RecordCount do begin
Temp.Append;
Temp.FieldByName("Product").AsString:=qOsn.FieldByName("Product").Value;
Temp.FieldByName("Osnovanye").AsString:=qOsn.FieldByName("Osnovanye").Value;
Temp.FieldByName("Discount").AsString:=qOsn.FieldByName("Discount").Value;
Temp.FieldByName("DateTime").AsDateTime:=qOsn.FieldByName("DateTime").Value;
if qOsn.FieldByName("Discount").Value=True then GetCena
else Cena1:=qOsn.FieldByName("Price").Value;
Temp.FieldByName("Marka").AsString:=qOsn.FieldByName("Marka").Value;
Temp.FieldByName("Osnovan").AsString:=qOsn.FieldByName("Name").Value;
Temp.FieldByName("Litr").AsFloat:=qOsn.FieldByName("LitFact").Value;
if qOsn.FieldByName("Report").Value=True then Temp.FieldByName("Summa").AsFloat:=qOsn.FieldByName("CurFact").Value
else if qOsn.FieldByName("Report").Value=False then Temp.FieldByName("Summa").AsFloat:=0;
Temp.FieldByName("Price").AsFloat:=qOsn.FieldByName("Price").Value;
s:=(qOsn.FieldByName("LitFact").Value*Cena1)-qOsn.FieldByName("CurFact").Value;
if s<0.4 then s:=0;
Temp.FieldByName("Delta").AsVariant:=s;
Temp.FieldByName("Report").AsBoolean:=qOsn.FieldByName("Report").Value;
qOsn.Next;
end;
Так вот, при вызове вот этого:if qOsn.FieldByName("Discount").Value=True then GetCena
Отчёт формируется минуты 2, а если опустить то мнгновенно.
Для чего это нужно объясняю: формируется отчёт по потерям на скидках, скидка этоs:=(qOsn.FieldByName("LitFact").Value*Cena1)-qOsn.FieldByName("CurFact").Value;
Цену, по которой был продан ГСМ со скидкой выдернуть из таблицы нет возможности, т.к. там указана только текущая цена, а цены меняются постоянно.
В самой таблице откуда дёргаются данные и переносятся в промежуточную таблицуTemp.FieldByName("Price").AsFloat:=qOsn.FieldByName("Price").Value;
Так вот, чтобы получить розничную цену на момент продажи необходимо взять предыдущую, первую попавшую розничную цену. Но благодаря этому отчёт формируется минуты 2, а это не есть гут.
Подскажите, как построить основной запрос, чтобы в нём дёргалась предыдущая, розничная цена, без всяких там моих извращений
← →
Поросенок Винни-Пух © (2008-11-28 10:00) [1]для начала сделайте цены как в хьюстоне. тогда потерь от скидок не будет.
так как скидок не потребуется
← →
Sergey13 © (2008-11-28 10:16) [2]> [0] petvv (28.11.08 09:25)
> Так вот, при вызове вот этого:
>
> if qOsn.FieldByName("Discount").Value=True then GetCena
>
> Отчёт формируется минуты 2, а если опустить то мнгновенно.
Значит запрос в GetCena работает медленно. Какие есть индексы на Statist?
И почему частично ты используешь параметры, а частично подстановку?
← →
Поросенок Винни-Пух © (2008-11-28 10:25) [3]И почему частично ты используешь параметры, а частично подстановку?
для парадокса это сильно повлияет на производительность?
оно что его, запрепарит если параметры будут?
← →
Sergey13 © (2008-11-28 10:37) [4]> [3] Поросенок Винни-Пух © (28.11.08 10:25)
> для парадокса это сильно повлияет на производительность?
никак не повлияет, мне просто интересно.
← →
Slym © (2008-11-28 11:22) [5]petvv (28.11.08 9:25)
Cena.FindLast;
Cena1:=Cena.FieldByName("Price").Value;
ты уверен что FindLast это последняя цена? я нет! потому что не ORDER BY DateTime
я бы сделал так
//эту операцию выполнить 1 раз перед началом работы
Cena.SQL.Add("select price from Statist where (Osnovanye=0) and (DateTime<:QDBeg) and (Product=:ProdID) ORDER BY DateTime DESC");
Cena.Prepare;
function TMainForm.GetCena(const Date:TDateTime;ProdID:integer;):variant;
begin
Cena.ParamByName("QDBeg").AsDateTime:=Date;
Cena.ParamByName("ProdID").Value:=ProdID;
Query1.Refresh;//непомню сработает или нет...
if not Cena.isEmpty then
result:=Cena.Fields[0].Value
else
result:=0;
end;
← →
Sergey13 © (2008-11-28 11:36) [6]> [0] petvv (28.11.08 09:25)
> Так вот, чтобы получить розничную цену на момент продажи
> необходимо взять предыдущую, первую попавшую розничную цену.
Наверное надо брать цену на максимальную дату меньше заданой, а не "первую попавшую"?
← →
Sergey13 © (2008-11-28 11:53) [7]как вариант1
перед расчетом выполнить запросselect s1.Product,s1.price
from Statist s1
where Statist.Osnovanye=0" and Statist.DateTime=
(select max(DateTime) from Statist s2 where s1.Product=s2.Product s2.DateTime<:QDBeg)
и в GetCena искать по нему locate по produkt.
Желателен индекс по Product+DateTime
вариант2
подумать и попробовать добавить этот запрос (передланный конечно) к основному, для исключения временной таблицы вообще как класса.
← →
petvv (2008-11-30 20:28) [8]
> вариант2подумать и попробовать добавить этот запрос (передланный
> конечно) к основному, для исключения временной таблицы вообще
> как класса.
Вот этот вариант подходит больше. Завтра на работе попробую навоять запрос. А промежуточную таблицу использовал потому, что пришли с вопросом сегодня, а сделать надо было вчера вот и пришлось использовать таблицу, чтобы сделать вчера.
← →
petvv (2008-11-30 20:38) [9]
> Наверное надо брать цену на максимальную дату меньше заданой,
> а не "первую попавшую"?
Я имел в виду тоже самое, только выразил свою мыслю криво.
← →
Loginov Dmitry © (2008-12-01 22:15) [10]> Цену, по которой был продан ГСМ со скидкой выдернуть из
> таблицы нет возможности, т.к. там указана только текущая
> цена, а цены меняются постоянно.
если "текущая цена" это НЕ тоже самое, что и "цена, по которой был продан ГСМ со скидкой", что тогда есть "текущая цена"?
Вообще-то исходных данных маловато. Мы видим, что есть некая таблица "Statist", в которую входят как минимум 3 поля: price, DateTime, Product, Osnovanye.
Также существует некая таблица, с которой осуществляется работа через набор данных "qOsn", включающая поля:
Product, Osnovanye, Discount, DateTime, Price, Marka, Name, LitFact, CurFact, Report. Это одна и таже таблица, или разные? Судя по наименованиям Statist и qOsn - наверно разные. Тогда какое назначение у таблицы qOsn и у таблицы Statist? И почему "Цену, по которой был продан ГСМ со скидкой выдернуть из таблицы нет возможности", с чем связаны данные особенности проектирования БД?
Страницы: 1 вся ветка
Текущий архив: 2009.10.11;
Скачать: CL | DM;
Память: 0.48 MB
Время: 0.005 c