Delphi 3 и создание приложений баз данных

Использование TQuery для получения агрегированных значений


Часто нужно подсчитать некоторые агрегированные значения данных (минимум, максимум, среднее, счетчик повторений). В дальнейшем полученные значения могут входить в какие-либо условные операторы или операторы выбора приложения.

Пусть, например, необходимо помещать уникальное значение в поле N_RASH (номер записи расхода со склада) в таблицу RASHOD. SQL-операторы INSERT, UPDATE не работают с автоинкрементными полями (локальные СУБД). Поэтому при занесении новой записи в таблицу RASHOD нужно определить уникальное значение поля N_RASH, для чего можно сделать запрос к таблице RASHOD:

WITH WorkQuery do begin

Close;

Clear;

SQL.Add('SELECT COUNT(*), MAX(N_RASH) AS M') ;

SQL.Add('FROM RASHOD') ;

Open;

END;//with

Пусть добавление новой записи реализуется в компоненте InsertQuery следующим динамическим оператором:

INSERT INTO RASHOD (N_RASH, DAT_RASH, KOLVO, TOVAR, POKUP)

VALUES(:N_RASH,:DAT_RASH, :KOLVO,:TOVAR, :POKUP)

Тогда в параметр :N_RASH следует поместить значение поля М набора данных компонента WorkQuery:

WITH InsertQuery do begin

ParamByName('N_RASH').AsInteger :=

WorkQuery.FieldByName('M').AsInteger + 1;

ExecSQL;

END; //with

ПОЯСНЕНИЕ.

После выполнения запроса в компоненте WorkQuery выдается результирующий НД, содержащий одну строку. Указатель текущей записи во вновь открытом НД всегда устанавливается на первую запись. Поэтому, даже если таблица RASHOD пуста, в поле М будет значение NULL, преобразуемое затем свойством AsInteger в 0.

Набор данных в компоненте WorkQuery мог бы не содержать ни одной строки (если в ТБД RASHOD не было ни одной строки) тогда и только тогда, если бы подсчет максимума производился оператором

SELECT MAX(N_RASH) AS M FROM RASHOD

Однако, применяя вместо этого оператор

SELECT COUNT(*), MAX(N_RASH) AS M FROM RASHOD

мы всегда получаем хотя бы одну запись в результирующем НД, поскольку COUNT(*) всегда возвратит значение, отличное от NULL.



Содержание раздела