Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
49
Добавлен:
17.04.2018
Размер:
124.42 Кб
Скачать

2.2. Агрегатные функции

Все функции, рассмотренные до этого, предназначены для обработки данных строка за строкой. В Oracle также есть агрегатные, или групповые, функции (group functions), позволяющие анализировать группы записей. Под группой записей понимается любой набор записей, имеющих что-то общее — например, относящихся к одному товару, одному отделу или одному временному интервалу. Для заданных групп агрегатные функции дают итоговую сумму, количество записей, а также среднее, наименьшее и наибольшее, значения для каждой группы. Эти функции очень удобны для статистического анализа.

Группы создаются предложением GROUP BY в операторе SELECT, а предложение HAVING фильтрует группы на основе групповых значений. В отличие от конструкции WHERE, фильтрующей записи до группирования, конструкция HAVING фильтрует уже сформированные группы.

При отсутствии предложений GROUP BY и HAVING в операторе SELECT возвращаемые агрегатными функциями значения будут относиться ко всему множеству записей таблицы.

SUM

Функция SUM суммирует значения и возвращает итог:

SELECT SUM(quantity) FROM purchase;

COUNT

Функция COUNT подсчитывает записи в таблице или значения в столбце. Например, чтобы определить, содержит ли таблица какие-нибудь записи, проще всего ввести такую команду:

SELECT COUNT(*) FROM purchase;

Однако ее не рекомендуется использовать, поскольку указание "*" вместо имени столбца неявно заставляете Oracle считывать всю таблицу. Это не принципиально для маленьких учебных таблиц, но представляет собой серьезную проблему в системах с сотнями тысяч, а тем более с миллиардами записей. Полное сканирование таблицы намного замедляет выдачу результата и вынуждает Oracle отвлекать компьютерные ресурсы от главных задач, для выполнения которых предназначалась база данных, что тормозит работу всей системы. Гораздо лучше указать какой-нибудь один столбец, по которому функция COUNT будет считать записи:

SELECT COUNT(product_name) FROM purchase;

Как правило, предпочтение отдается первому столбцу таблицы — по причинам, которые будут объяснены в следующей теме. Можно поступить еще проще, указав в качестве аргумента функции COUNT не имя столбца, а литеральное значение:

SELECT COUNT(1) FROM purchase;

Строго говоря, это заставляет Oracle возвращать значение "1" для каждой записи в таблице. С тем же успехом можно подставить в функцию фразу "Считай!"; какое именно литеральное значение будет использовано — неважно, поскольку само это значение функция игнорирует. Она лишь подсчитывает записи и сообщает, сколько их было найдено.

Функция COUNT имеет одно интересное свойство: если указать столбец таблицы, записи которой подсчитываются, будут учтены только записи, содержащие в этом столбце какое-либо значение. Этим можно воспользоваться для определения процента записей, имеющих null-значение в определенном столбце. После ввода показанного ниже кода первая команда выведет общее количество записей в таблице; вторая команда выдаст тот же результат, поскольку ни в одной из записей название товара не является пустым; третья команда сообщит, сколько записей содержит заполненный столбец LAST_STOCK_DATE; последняя команда даст процент записей, в которых этот столбец заполнен. Информация такого рода может пригодиться, когда необходимо определить полезность какого-либо столбца.

SELECT COUNT(1) FROM product;

SELECT COUNT(product_name) FROM product;

SELECT COUNT(last_stock_date) FROM product;

SELECT COUNT(last_stock_date) / COUNT(product_name) "% заполненных записей"

FROM product;

AVG

Функция AVG возвращает среднее значение по указанному столбцу. Поскольку для этого функция должна выполнить фактическое считывание всего столбца, нет смысла указывать" \" или какой-либо другой литерал в качестве аргумента; необходимо указать имя столбца. Например, чтобы узнать среднюю цену товаров из таблицы PRODUCT, нужно ввести следующий оператор:

SELECT AVG(product_price) FROM product;

MIN

Функция MIN возвращает наименьшее из значений, содержащихся в указанном столбце. Например, чтобы узнать, сколько стоит самый дешевый товар из таблицы PRODUCT, можно ввести такую команду:

SELECT MIN(product_price) FROM product;

MAX

Как вы наверняка догадались, функция МАХ возвращает наибольшее из значений указанного столбца. Например, чтобы узнать максимальную цену товара в таблице PRODUCT, можно воспользоваться следующей командой:

SELECT MAX(product_price) FROM product;

Функция MAX применяется в целом ряде случаев. Например, может встать вопрос о сокращении длины текстового столбца существующей таблицы. Чтобы узнать, какая часть столбца действительно используется, нужно определить максимальную длину текста в этом столбце. Это легко сделать, указав в качестве аргумента функции МАХ длину столбца, как показано во второй из следующих команд:

DESC purchase;

SELECT MAX(LENGTH(product_name)) FROM purchase;

Подведение итогов по группам данных

Добавление предложения GROUP BY в оператор SELECT указывает на необходимость применить агрегатную функцию к каждой сформированной группе записей:

SELECT product_name, SUM(quantity) FROM purchase

GROUP BY product_name;

В предложении GROUP BY указывается столбец, по значениям которого будет выполняться группирование.

В оператор SELECT можно включать несколько различных агрегатных функций. Например, один и тот же оператор может выдавать суммарное, среднее, наименьшее и наибольшее значения по каждой группе, а также подсчитывать число записей в группах. Приведенный ниже код показывает, как это делается. Чтобы результаты поместились на экране, столбец PRODUCT_NAME сужен с помощью функции SUBSTR.

SELECT SUBSTR(product_name, 1, 15) "Product",

SUM(quantity) "Total Sold", AVG(quantity) "Average", COUNT(quantity) "Transactions",

MIN(quantity) "Fewest", MAX(quantity) "Most" FROM purchase

GROUP BY product_name;

При группировании записей предложение WHERE по-прежнему фильтрует отдельные записи, тем самым исключая их из вычислений, выполняемых агрегатными функциями.

Однако после создания групп возникает новая задача: фильтрация самих групп на основе групповой информации. Предположим, что предприятию не хватает складских площадей и оно намерено сократить запас товаров на складе. Для реализации этого мероприятия требуется составить список плохо продающихся товаров — например, тех, для которых общий объем продаж составляет менее пяти штук. Здесь и пригодится предложение HAVING, которое фильтрует группы на основе групповых значений. В отличие от предложения WHERE, фильтрующей записи до группирования, предложение HAVING фильтрует уже сформированные группы:

SELECT SUBSTR(product_name, 1, 15) "Product",

SUM(quantity) "Total Sold", AVG(quantity) "Average", COUNT(quantity) "Transactions",

MIN(quantity) "Fewest", MAX (quantity) "Most" FROM purchase

GROUP BY product_name

HAVING SUM(quantity) < 5;

Оператор SELECT включит в выходные данные только плохо продающиеся товары. Если нужно решить обратную задачу — составить список хорошо продающихся товаров, достаточно изменить условие в предложение HAVING, как показано ниже:

SELECT SUBSTR(product_name, 1, 15) "Product",

SUM(quantity) "Total Sold", AVG(quantity) "Average", COUNT(quantity) "Transactions",

MIN(quantity) "Fewest", MAX (quantity) "Most" FROM purchase

GROUP BY product_name

HAVING SUM(quantity) >= 5;

Соседние файлы в папке лекции оракл