Использование 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.