Форум: "Базы";
Текущий архив: 2003.03.31;
Скачать: [xml.tar.bz2];
ВнизSQL Найти похожие ветки
← →
Фагот (2003-03-06 13:11) [0]Здравствуйте!
У меня есть SQL-запрос, который для большой таблицы вополняется очень долго. Можно ли сделать так, чтобы первый запрос составлял набор данных (часть таблицы), а второй с этим набором работал и мог вызываться кагда угодно и сколько угодно. Короче говоря, чтобы Query2 работал с результатами работыв Query1.
Если это всё-же возможно, то объясните, пожалуйста, попдробнее.
← →
Dms (2003-03-06 13:31) [1]нельзя ... тут тебе придется обойтись построением сложного sql запроса
← →
DieHard (2003-03-06 13:38) [2]можно попробовать создавать временную таблицу с результами первого запроса
← →
Smithson (2003-03-06 13:39) [3]Ну почему же. Если результат долго запроса загнать в таблицу - временную - то потом все другие запросы смогут черпать из этой таблицы
← →
Dms (2003-03-06 13:41) [4]что за СУБД ?
← →
Фагот (2003-03-06 13:43) [5]СУБД - Paradox
← →
Dms (2003-03-06 13:44) [6]тогда удачи со временными таблицами :)
← →
Dms (2003-03-06 13:45) [7]если важна скорость - откажись от Paradox. Используй InterBase или еще что, но оптимизируя приложения под pAradox по скорости далеко не уйдешь ...
← →
Наталия (2003-03-06 14:22) [8]Можно. Читай help по LocalSQL. Сохраняешь текст первого запроса в файле с расширением sql и второй запрос делаешь к этому файлу.
Это как бы аналог view. Если я правильно вопрос поняла.
← →
oomneeq (2003-03-06 14:47) [9]Вот это тебе должно помочь
Надеюсь разберешься
В свое время делал для парадокса
//Для начала используемые в примере функции
//
function SQLSet(Alias,SQLStr:string):TRxQuery;
var TryAgain:boolean;
TmpTabl : TTable;
S : String;
begin
Result:=TRxQuery.Create(nil);
Result.ParamCheck:=false; //to prevent Alias sign to be interpreded as Param sign (:)
try
with Result do begin
if Alias<>"" then begin
DataBaseName:=Alias;
SQLStr:=DelAllSubstr(":"+Alias+":",SQLStr);
end;
SQL.Text:=SQLStr;
repeat
try
TryAgain:=false;
Open;
except
on E:EDBEngineError do begin
TryAgain:=(E as EDBEngineError).Errors[0].Errorcode=10245;{File is locked}
if TryAgain then Cry("Захват данных другим пользователем. Нажмите OK чтобы повторить попытку.");
if not TryAgain then raise;
end
else raise
end;
until not Tryagain;
end;
except
Result.Free;
raise;
end
end;
//вот та самая VIEW-эмуляторка под парадокс
//ViewFN - имя файла для временной таблицы, куда помещать результаты
//ф-я возвращает то же имя, чтоб можно было его вставлять
//в следующий запрос - таблица-то(файл) уже создана
function KHQuasiView(ViewFN,SQLStmnt:string):string;
var TmpQ:TQuery;
TmpT:TTable;
begin
TmpQ:=SQLSet(SQLStmnt);
TmpT:=TTable.Create(nil);
TmpT.TableName:=ViewFN;
TmpT.BatchMove(TmpQ,batCopy);
TmpQ.Free;
Result:="""+ViewFN+""";
TmpT.Free;
end;
//А вот пример использования
.....
//Первый запрос
S1:=Format("SELECT %s as CODE,SUM(%s) as QTY "+
" FROM %s,%s,"%s" WHERE %s=DETLCODE and %s=%s and "+
"(%s>=%s) and (%s<%s) GROUP BY %s",
[xdtlCode,xdtlQTY,Inventory.InvSaleNak.QDOSFileName,
Inventory.InvSaleNak.DetlTable.QDOSFileName,FN2,
xdtlCODE,xdtlNak,xnakID,xnakRegDate,SQLDate(BegPD),
xnakRegDate,SQLDate(EndPD+1),xdtlCode]);
end;
//Второй запрос, обращается к результатам первого
FN5:=TempDBFN;
S:=Format("select B.*, QTY as Продано "+
" from "%s" B left outer join %s on (B.КОД=CODE)",
[FN5, KHQuasiView(FN5,S1)]);
Q:=SQLSet(S); //получили результат итогового запроса
← →
oomneeq (2003-03-06 14:52) [10]поправка
FN5:=TempDBFN; // это просто получение имени временного файла
S:=Format("select B.*, QTY as Продано "+
" from "%s" B left outer join %s on (B.КОД=CODE)",
[ <имя файла другой таблицы>,KHQuasiView(FN5,S1)]);
Q:=SQLSet(S); //получили результат итогового запроса
← →
Val (2003-03-06 14:56) [11]хотелось бы посмотреть и на сам запрос
← →
oomneeq (2003-03-07 13:04) [12]>Val © (06.03.03 14:56)
>хотелось бы посмотреть и на сам запрос
?
cм. >oomneeq © (06.03.03 14:52)
Может такой пример будет проще к пониманию:
S1:="select C.X1 as F1,min(C.X2) as F2 from C group by C.X1";
S2:="select A.F1,A.F2,B.F1,B.F2 from A," +QuasiView("TmpTableName",S1)+" B "+
"where A.F1=B.F1";
В момент присвоения S2 данного выражения происходит:
Вызов функции QuasiView, которая
1)выполнит запрос S1 и поместит результат в файл TmpTableName
2)возвратит своим резалтом TmpTableName, которое может быть использован при составлении других запросов.
В данном случае S2.
после чего к TmpTableName можно делать запрос.
что и будет сделано, когда будет выполняться S2
То есть в конечном итоге S2 будет выглядеть так
"select A.F1,A.F2,B.F1,B.F2 from A, TmpTableName B where A.F1=B.F1";
На это тебе хотелось посмотретЬ ?
NB
S1 я специально сделал с агрегацией, чтоб было оправдано разбиение на два этапа. в противном случае можно было бы обойтись одним запроосом..
На серверных платформах для этого делается Select from Select ...
но для локального парадокса нужно вот так извращаться.
← →
Val (2003-03-07 13:17) [13]>oomneeq © (07.03.03 13:04)
вопрос был адресован автору.
> На серверных платформах для этого делается Select from Select
> ...
> но для локального парадокса нужно вот так извращаться.
можно попробовать применить Local Views.
← →
Фагот (2003-03-09 10:01) [14]В принципе, второй запрос делает изменения в таблице, поэторму, мне кажется, нельзя использовать временные таблицы, потому как потом из этой временной надо переносить в настоящую - в принципе опять те же грабли...
← →
Anatoly Podgoretsky (2003-03-09 10:08) [15]Сказали же покажи запрос
← →
Фагот (2003-03-11 11:46) [16]Ну вот запрос
Insert Table2
Set Table2.Field2=(Select (MAX Field2) FROM Table1 where Table2.Field2=Table1.Field1)
← →
Johnmen (2003-03-11 11:51) [17]А посмотреть синтаксис INSERT влом ?
← →
Val (2003-03-11 11:56) [18]а как с индексами на участвующие в запросе поля?
← →
Val (2003-03-11 12:01) [19]>Johnmen © (11.03.03 11:51)
похоже, что автор просто ошибся в приведенном здесь тексте, поскольку утверждает, что данный запрос работает.
← →
Фагот (2003-03-11 12:18) [20]Прошу прощения, но я на самом деле соврал в запросе. Реальный запрос вот:
UPDATE Topic
SET Topic.FirstDate=(SELECT MAX(Stage.SecondDate) FROM Stage WHERE Topic.Topic=Stage.Topic AND Topic.FirstDate IS NULL)
← →
Johnmen (2003-03-11 12:26) [21]UPDATE Topic
SET Topic.FirstDate=(SELECT MAX(Stage.SecondDate) FROM Stage WHERE Topic.Topic=Stage.Topic)
WHERE Topic.FirstDate IS NULL
А в чем все-таки проблема ?
← →
Фагот (2003-03-11 13:12) [22]Дак запрос-то работает крайне медленно!!!
Я хочу единожды слелать выборку из таблицы, а потом уже в этой выборке несколько раз делать апдейты! Если каждый раз применять этот запрос к полной таблице, то на моей тачке этот запрос выполняется около часа. Считай, что он каждый раз смотрит всю таблицу.
Johnmen"у - это условие никак не ускоряет выполнение запроса.
← →
Johnmen (2003-03-11 13:21) [23]>Фагот © (11.03.03 13:12)
То есть, Topic.Topic могут повторяться ?
>...это условие никак не ускоряет выполнение запроса
Просто оно корректное...:)
← →
Фагот (2003-03-11 15:39) [24]Johnmen"у
Это конечно хорошо, что корректнее. Но вопрос изначально стоял в том, чтобы иметь возможность апдейтить не всю таблицу, а только её часть. В том запросе, который привёл я выбока из таблицы делается каждый раз, когда я делаю запрос, а мне посути, нужна только небольшая её часть.
← →
sunrider (2003-03-11 15:46) [25]Можно поробовать для работы с результатом запроса
использовать ClientDataset, а данные передать в него как поток
XML. Тогда даже в случае сложного запроса из разных таблиц можно
редактировать все поля и сохранять данные в нужных таблицах
← →
ЮЮ (2003-03-12 07:10) [26]Это твой запрос применялся ко всей таблице, причем, если NOT (Topic.FirstDate IS NULL), то опять должен был присвоиться NULL (не корректировка, а качели какие-то), а запрос Johnmen © (11.03.03 12:26) как раз и применяется лишь к тем записям, где Topic.FirstDate IS NULL, а не ко всей таблице (см.WHERE Topic.FirstDate IS NULL)
А долго, возможно, из-за твоего предыдущего запроса, обNILLившего до этого поле FirstDate таблицы Topic.
Попробуй повторить и почувствуй разницу :-)
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2003.03.31;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.007 c