-
снежок (23.04.10 14:26) [0]Привет!
В общем, нужно оптимизировать задачу. Весь мозг уже сломал.
На данный момент имеем запрос:SELECT PLACELIST.*, RAIONS.NAME RNAME, PLACES.C_NAME PNAME, PLACES.SIDE_COUNT SC FROM PLACELIST
INNER JOIN PLACES ON (PLACES.ID=PLACELIST.C_TYPE)
INNER JOIN RAIONS ON (RAIONS.ID=PLACELIST.C_RAIONID)
который выдает весь список размещений, который имеется в базе.
Задача в следующем: нужно для каждой записи размещения (а в каждой записи может быть PLACES.SUDE_COUNT (количество сторон) от 1 до 8 и для каждой из них нужно вытащить из другой таблицы (ZAKAZY) наличие или отсутствие записей, соответствующих данному размещению и данной стороне.
Сейчас я сделал так: сначала заполняю грид данными, а потом в цикле пробегаюсь по каждой ячейке и запрашиваю COUNT. Но для 10 записей это занимает 3 секунды, а записей в таблице PLACELIST около тысячи...
Собственно вопрос: как можно составить запрос таким образом, чтобы в ответ он выдавал что-то типа:
[НазваниеРазмещения] [НомерСтороны] [Кол-во заказов]
и так далее?
Премного благодарен. Firebird 2. -
Виталий Панасенко(дом) (23.04.10 14:32) [1]а не пробовал вместо грида(вообще-то он только показывает, а данные в датасете, к нему привязанному) использовать EXECUTE BLOCK+курсор?
-
снежок (23.04.10 14:37) [2]я поэтому и спрашиваю как лучше. я не знаю, как пользоваться execute block. мне бы примерчик :-)
-
Виталий Панасенко(дом) (23.04.10 14:45) [3]SQL Language Extension: EXECUTE BLOCK
Function:
Allow execute PL-SQL block as if it is stored procedure.
Supports input and output parameters
Autor:
Vlad Horsun <horsun@kdb.dp.ua>
Syntax:
EXECUTE BLOCK [ (param datatype = ?, param datatype = ?, ...) ]
[ RETURNS (param datatype, param datatype, ...) }
AS
[DECLARE VARIABLE var datatype; ...]
BEGIN
...
END
Client-side:
The call isc_dsql_sql_info with parameter isc_info_sql_stmt_type returns
- isc_info_sql_stmt_select, if block has output parameters.
Semantics of a call is similar to SELECT query - client has open cursor,
can fetch data from it, and must close it after use.
- isc_info_sql_stmt_exec_procedure, if block has no output parameters.
Semantics of a call is similar to EXECUTE query - client has no cursor,
execution runs until first SUSPEND or end of block
The client should preprocess only head of the SQL statement or use '?'
instead of ':' as parameter indicator because in a body of the block may be links
to local variables and \ or parameters with a colon ahead.
Example:
User SQL is
EXECUTE BLOCK (X INTEGER = :X) RETURNS (Y VARCHAR)
AS
DECLARE V INTEGER;
BEGIN
INSERT INTO T(...) VALUES (... :X ...);
SELECT ... FROM T INTO :Y;
SUSPEND;
END
Preprocessed SQL is
EXECUTE BLOCK (X INTEGER = ?) RETURNS (Y VARCHAR)
AS
DECLARE V INTEGER;
BEGIN
INSERT INTO T(...) VALUES (... :X ...);
SELECT ... FROM T INTO :Y;
SUSPEND;
END
каталог doc\sql.extensions - там много интересного.. EXECUTE BLOCK позволяет как-бы исполнять скрипт.. ал-ля ХП, но без создания оных в БД -
Виталий Панасенко(дом) (23.04.10 14:45) [4]SQL Language Extension: EXECUTE BLOCK
Function:
Allow execute PL-SQL block as if it is stored procedure.
Supports input and output parameters
Autor:
Vlad Horsun <horsun@kdb.dp.ua>
Syntax:
EXECUTE BLOCK [ (param datatype = ?, param datatype = ?, ...) ]
[ RETURNS (param datatype, param datatype, ...) }
AS
[DECLARE VARIABLE var datatype; ...]
BEGIN
...
END
Client-side:
The call isc_dsql_sql_info with parameter isc_info_sql_stmt_type returns
- isc_info_sql_stmt_select, if block has output parameters.
Semantics of a call is similar to SELECT query - client has open cursor,
can fetch data from it, and must close it after use.
- isc_info_sql_stmt_exec_procedure, if block has no output parameters.
Semantics of a call is similar to EXECUTE query - client has no cursor,
execution runs until first SUSPEND or end of block
The client should preprocess only head of the SQL statement or use '?'
instead of ':' as parameter indicator because in a body of the block may be links
to local variables and \ or parameters with a colon ahead.
Example:
User SQL is
EXECUTE BLOCK (X INTEGER = :X) RETURNS (Y VARCHAR)
AS
DECLARE V INTEGER;
BEGIN
INSERT INTO T(...) VALUES (... :X ...);
SELECT ... FROM T INTO :Y;
SUSPEND;
END
Preprocessed SQL is
EXECUTE BLOCK (X INTEGER = ?) RETURNS (Y VARCHAR)
AS
DECLARE V INTEGER;
BEGIN
INSERT INTO T(...) VALUES (... :X ...);
SELECT ... FROM T INTO :Y;
SUSPEND;
END
каталог doc\sql.extensions - там много интересного.. EXECUTE BLOCK позволяет как-бы исполнять скрипт.. ал-ля ХП, но без создания оных в БД -
Виталий Панасенко(дом) (23.04.10 14:46) [5]вах.. Укртелеком глючит..извиняюсь за повтор
-
> [0] снежок (23.04.10 14:26)
Не уверен что правильно понял вопрос, но (по тому как понял) можно попробоватьSELECT PLACELIST.*, RAIONS.NAME RNAME, PLACES.C_NAME PNAME, PLACES.SIDE_COUNT SC,
(select count(*) from zakazy where ...) count_zakaz
FROM PLACELIST
INNER JOIN PLACES ON (PLACES.ID=PLACELIST.C_TYPE)
INNER JOIN RAIONS ON (RAIONS.ID=PLACELIST.C_RAIONID) -
снежок (23.04.10 15:21) [7]
-
снежок (23.04.10 15:24) [8]Кстати, твое решение с count не подходит, т.к. оно считает _все_ совпадения без учета номера стороны...
-
> [8] снежок (23.04.10 15:24)
> т.к. оно считает _все_ совпадения без учета номера стороны...
А готовый конечный запрос можно глянуть? -
Виталий Панасенко(дом) (23.04.10 17:22) [10]это я так понял, учет наружки? нет желания объединится?
-
снежок (23.04.10 21:47) [11]Есть конечно стучись пять шесть девять 7 двадцать 5 шестьдесятдва)) у меня много наработок на эту тему и эта не последняя.