Как узнать количество моделей ПК, выпускаемых тем или иным поставщиком? Как определить
среднее значение цены на компьютеры, имеющие одинаковые технические характеристики? На эти и
многие другие вопросы, связанные с некоторой статистической информацией, можно получить ответы
при помощи итоговых (агрегатных) функций. Стандартом предусмотрены следующие агрегатные функции:
Функция | Описание |
COUNT(*) | Возвращает количество строк источника записей. |
COUNT(<имя поля>) | Возвращает количество значений в указанном столбце. |
SUM(<имя поля>) | Возвращает сумму значений в указанном столбце. |
AVG(<имя поля>) | Возвращает среднее значение в указанном столбце. |
MIN(<имя поля>) | Возвращает минимальное значение в указанном столбце. |
MAX(<имя поля>) | Возвращает максимальное значение в указанном столбце. |
Все эти функции возвращают единственное значение. При этом функции COUNT, MIN и MAX применимы к любым типам данных, в то время как SUM и AVG используются только для числовых полей. Разница между функцией COUNT(*) и COUNT(<имя поля>) состоит в том, что вторая при подсчете не учитывает NULL-значения.
Пример. Найти минимальную и максимальную цену на персональные компьютеры:
SELECT MIN(price) AS Min_price, MAX(price) AS Max_price FROM PC; |
Min_price | Max_price |
350.0 | 980.0 |
Пример. Найти имеющееся в наличии количество компьютеров, выпущенных производителем А:
SELECT COUNT(*) AS Qty FROM PC WHERE model IN (SELECT model FROM Product WHERE maker = 'A'); |
Qty |
7 |
Пример. Если же нас интересует количество различных моделей, выпускаемых производителем А, то запрос можно сформулировать следующим образом (пользуясь тем фактом, что в таблице Product каждая модель записывается один раз):
SELECT COUNT(model) AS Qty_model FROM Product WHERE maker = 'A'; |
Qty_model |
7 |
Пример. Найти количество имеющихся различных моделей, выпускаемых производителем А. Запрос похож на предыдущий, в котором требовалось определить общее число моделей, выпускаемых производителем А. Здесь же требуется найти число различных моделей в таблице PC (т.е. имеющихся в продаже).
Для того, чтобы при получении статистических показателей использовались только уникальные значения, при аргументе агрегатных функций можно использовать параметр DISTINCT. Другой параметр ALL используется по умолчанию и предполагает подсчет всех возвращаемых значений в столбце. Оператор,
SELECT COUNT(DISTINCT model) AS Qty FROM PC WHERE model IN (SELECT model FROM Product WHERE maker = 'A'); |
Qty |
2 |
Если же нам требуется получить количество моделей ПК, производимых каждым производителем, то потребуется использовать предложение GROUP BY, синтаксически следующего после предложения WHERE.
SELECT model, COUNT(model) AS Qty_model, AVG(price) AS Avg_price FROM PC GROUP BY model; |
model | Qty_model | Avg_price |
1121 | 3 | 850.0 |
1232 | 4 | 425.0 |
1233 | 3 | 843.33333333333337 |
1260 | 1 | 350.0 |
Если бы в SELECT присутствовал столбец с датой, то можно было бы вычислять эти показатели для каждой конкретной даты. Для этого нужно добавить дату в качестве группирующего столбца, и тогда агрегатные функции вычислялись бы для каждой комбинации значений (модель−дата).
Существует несколько определенных правил выполнения агрегатных функций:
Итак, если запрос не содержит предложения GROUP BY, то агрегатные функции, включенные в предложение SELECT, исполняются над всеми результирующими строками запроса. Если запрос содержит предложение GROUP BY, каждый набор строк, который имеет одинаковые значения столбца или группы столбцов, заданных в предложении GROUP BY, составляет группу, и агрегатные функции выполняются для каждой группы отдельно.
Если предложение WHERE определяет предикат для фильтрации строк, то предложение HAVING применяется после группировки для определения аналогичного предиката, фильтрующего группы по значениям агрегатных функций. Это предложение необходимо для проверки значений, которые получены с помощью агрегатной функции не из отдельных строк источника записей, определенного в предложении FROM, а из групп таких строк. Поэтому такая проверка не может содержаться в предложении WHERE.
Пример. Получить количество ПК и среднюю цену для каждой модели при условии, что средняя цена менее $800:
SELECT model, COUNT(model) AS Qty_model, AVG(price) AS Avg_price FROM PC GROUP BY model HAVING AVG(price) < 800; |
model | Qty_model | Avg_price |
1232 | 4 | 425.0 |
1260 | 1 | 350.0 |
Заметим, что в предложении HAVING нельзя использовать псевдоним (Avg_price), используемый для именования значений агрегатной функции. Дело в том, что предложение SELECT, формирующее выходной набор запроса, выполняется предпоследним перед предложением ORDER BY.
Ниже приведен порядок обработки предложений в операторе SELECT:
Этот порядок не соответствует синтаксическому порядку общего формата оператора SELECT, представленному ниже:
SELECT [DISTINCT | ALL]{*
| [<выражение для столбца> [[AS] <псевдоним>]] [,…]}
FROM <имя таблицы> [[AS] <псевдоним>] [,…]
[WHERE <предикат>]
[[GROUP BY <список столбцов>]
[HAVING <условие на агрегатные значения>] ]
[ORDER BY <список столбцов>]
Рекомендуемые упражнения: 10, 11, 12, 14, 15, 20, 22, 33, 43, 51, 52.
Начало | Упражнения SELECT (рейтинговые этапы) | Упражнения DML | Разработчики |