Шрифт:
SELECT PRODUCT_TYPE, SUM(NUMBER_SOLD) AS SUM_SALES
FROM TABLEA
WHERE SERIAL_NO BETWEEN 'A' AND 'K'
GROUP BY PRODUCT_TYPE;
Результат может быть похожим на следующий:
PRODUCT TYPE SUM SALES
Gadgets 174
Whatsits 25
Widgets 117
Firebird предоставляет широкий диапазон возможностей группирования с весьма ограниченными правилами управления их логикой.
! ! !
ВНИМАНИЕ! Если вы конвертируете базу данных из InterBase в Firebird, то это одна из областей, где вам нужно помнить о различиях. Firebird является менее терпимым к нелогичным спецификациям группирования, чем его предшественник. Это позволяет исключить возможность выполнения запросов, возвращающих некорректные результаты.
. ! .
Обобщающие выражения обсуждаются в главе 21. Подробную информацию о предложении GROUP BY см. в главе 23.
Необязательное предложение HAVING может быть использовано вместе со спецификацией группирования для включения или исключения строк или групп, как это делает предложение WHERE, ограничивая набор строк. Часто в группирующих запросах предложение HAVING может заменить предложение WHERE. При этом, поскольку HAVING оперирует с промежуточным набором, созданным в качестве входа для спецификации GROUP BY, может оказаться более экономичным использование условия WHERE для ограничения количества строк и условия HAVING для ограничения количества групп.
Изменим предыдущий пример, добавив предложение HAVING для получения только тех PRODUCT_TYPE, которые имели количество продаж больше 100:
SELECT PRODUCT_TYPE, SUM(NUMBER_SOLD) AS SUM_SALES
FROM TABLEA
WHERE SERIAL_NO BETWEEN 'A' AND 'K'
AND PRODUCT_TYPE = 'WIDGETS'
GROUP BY PRODUCT_TYPE
HAVING SUM(NUMBER_SOLD) > 100;
Вывод будет таким:
PRODUCT TYPE SUM SALES
Widgets 117
Наборы UNION формируются объединением двух или более спецификаций запросов, которые могут использовать различные таблицы, в один выходной набор. Единственное ограничение - выходные столбцы в каждой выходной спецификации должны соответствовать по степени, типу и размеру. Это означает, что в каждом выходе должно быть то же количество столбцов в том же порядке слева направо, и каждый столбец должен быть совместим по типу данных и размеру.
По умолчанию UNION убирает дубликаты в финальном выходном наборе. Для сохранения всех дубликатов добавьте ключевое слово ALL [71] .
71
Если два набора, объединяемых UNION, принципиально не будут содержать дубликатов строк, необходимо использовать UNION ALL, чтобы сервер не занимался зря работой по удалению несуществующих дубликатов строк.
– Прим. науч. ред.
Наборы UNION подробно обсуждаются в главе 23.
Предложение PLAN позволяет включить план запроса в спецификацию запроса. План является инструкцией оптимизатору по использованию отдельных индексов, порядка соединения и методов доступа для запроса. Оптимизатор создает свой собственный план при подготовке оператора запроса. Вы можете просматривать план в isql и многих других доступных утилитах графического интерфейса. Обычно "оптимизатор знает лучше", но у вас может быть опыт использования различных планов оптимизатора, когда запрос работал медленно.
Планы запросов и синтаксис выражений плана обсуждаются в разд. "Тема оптимизации" главы 22.
Используйте это предложение, когда вам нужно сортировать выходной набор. Например, следующий оператор дает список имен, отсортированный в алфавитном порядке по фамилии и имени:
SELECT EMP_NO, LAST_NAME, FIRST_NAME FROM EMPLOYEE
ORDER BY LAST_NAME, FIRST_NAME;
В отличие от столбцов GROUP BY столбцы в ORDER BY не обязательно должны присутствовать в выходной спецификации (предложение SELECT). Идентификатор любого упорядочиваемого столбца, который также появляется в выходной спецификации, может быть заменен на его порядковый номер в выходной спецификации при подсчете слева направо:
SELECT EMP_NO, LAST_NAME, FIRST_NAME FROM EMPLOYEE
ORDER BY 2, 3;
Обратите особое внимание на индексы для столбцов, которые будут использованы для сортировки (см. главу 18). Подробнее о синтаксисе и проблемах см. в главе 23.
Его синтаксис:
[FOR UPDATE [OF col1 [,col2..]] [WITH LOCK]]
Вообще говоря, предложение FOR UPDATE имеет смысл только в контексте оператора SELECT, который используется для задания именованных курсоров. Оно указывает серверу, чтобы тот ждал вызова FETCH, читал бы одну строку в курсор для операции "текущей строки" и затем ожидал бы следующий вызов FETCH. После того как все записи будут прочитаны, они становятся доступными для операций изменения.