Агрегирование данных в запросах
В SQL существует ряд специальных стандартных функций (SQL-функций). Кроме специального случая COUNT(*) каждая из этих функций оперирует совокупностью значений столбца некоторой таблицы и создает единственное значение, определяемое так:
COUNT - число значений в столбце;
SUM - сумма значений в столбце;
AVG - среднее значение в столбце;
MAX - самое большое значение в столбце;
MIN - самое малое значение в столбце.
Для функций SUM и AVG рассматриваемый столбец должен содержать числовые значения.
Замечание. Следует отметить, что здесь «столбец» - это столбец виртуальной таблицы (например, представления), в которой могут содержаться данные не только из столбца базовой таблицы, но и данные, полученные путем функционального преобразования и (или) связывания символами арифметических операций значений из одного или нескольких столбцов. При этом выражение, определяющее столбец такой таблицы, может быть сколь угодно сложным, но не должно содержать SQL-функций (вложенность SQL-функций не допускается). Однако из SQL-функций можно составлять любые выражения.
Аргументу всех функций, кроме COUNT(*), может предшествовать ключевое слово DISTINCT (различный), указывающее, что избыточные дублирующие значения должны быть исключены перед тем, как будет применяться функция. Специальная же функция COUNT(*) служит для подсчета всех без исключения строк в таблице (включая дубликаты).
Пример 4.14 Чтобы найти сумму всех покупок, необходимо ввести следующий запрос: SELECT SUM(amt) FROM Порядки;В результате будет выведено значение 26658.4 без подписи поля.
Пример 4.15 Подсчитать число строк в таблице Заказчики: SELECT COUNT (*) FROM Заказчики;В результате будет выведено значение 7.
Фраза GROUP BY (группировать по …) инициирует перекомпоновку указанной в предложении FROM таблицы по группам, каждая из которых имеет одинаковые значения в столбце, заданном в столбце GROUP BY, затем к каждой группе применяется заданная функция и оператор SELECT выводит значения для каждой группы.
Пример 4.16 Найти наибольшую сумму приобретений, полученную каждым продавцом: SELECT snum, MAX (amt) FROM Порядки GROUP BY snum;Вывод для этого запроса:
snum ------ -------- 1001 767.19 1002 1713.23 1003 75.75 1014 1309.95 1007 1098.16 Замечание. В список отбираемых полей оператора SELECT, содержащего раздел GROUP BY, можно включать только агрегатные функции и поля, которые входят в условие группировки. Поэтому команда SELECT onum, snum, MAX (amt) FROM Порядки GROUP BY snum; не будет выполнена и появится сообщение о синтаксической ошибке. Причина ошибки в том, что в список отбираемых полей включено поле onum, которое не входит в раздел GROUP BY.Можно также использовать GROUP BY с несколькими полями, задавая уровни группировки. Пример 4.17 Вывести наибольшую сумму приобретений, получаемую каждым продавцом каж-дый день: SELECT snum, odate, MAX (amt) FROM Порядки GROUP BY snum, odate;Вывод для этого запроса:
snum odate ------ ---------- -------- 1001 10/03/2003 767.19 1001 10/05/2003 4723.00 1001 10/06/2003 9891.88 1002 10/03/2003 5160.45 1002 10/04/2003 75.75 1002 10/06/2003 1309.95 1003 10/04/2003 1713.23 1014 10/03/2003 1900.10 1007 10/03/2003 1098.16 Фраза HAVING играет такую же роль для групп, что и фраза WHERE для строк: она используется для исключения групп, точно так же, как WHERE используется для исключения строк. Эта фраза включается в предложение лишь при наличии предложения GROUP BY, а выражение в предложении HAVING должно принимать единственное значение для группы, т.е. использоваться агрегатная функция. Пример 4.18 Предположим, что в предыдущем примере, необходимо увидеть только максимальные суммы приобретений, значение которых выше $3000.00: SELECT snum, odate, MAX (amt) FROM Порядки GROUP BY snum, odate HAVING MAX (amt) > 3000.00;Замечание. В одном запросе могут встретиться как условия отбора строк в разделе WHERE, так и условия отбора групп в разделе HAVING. Условия отбора групп нельзя перенести из раздела HAVING в раздел WHERE. Аналогично и условия отбора строк нельзя перенести из раздела WHERE в раздел HAVING, за исключением условий, включающих поля из списка группировки GROUP BY. Добавим в запрос предыдущего примера раздел WHERE:
SELECT snum, MAX (amt) FROM Порядки WHERE snum IN (1002,1007) GROUP BY snum HAVING MAX (amt) > 3000.00;Эта команда будет выполняться в следующей последовательности:1. отбираются строки, удовлетворяющие предикату в предложении WHERE;2. выявляются группы, заданные предложением GROUP BY;3. внутри каждой группы вычисляется значение функции (MAX (amt) );4. исключаются из вывода группы, не удовлетворяющие условию, указанному в предложении HAVING.В список вывода оператора SELECT можно добавить любые строковые константы и вычисляемые выражения.
Пример 4.19 Представить комиссионные продавцов в процентном отношении (а не в виде десятичных чисел): SELECT snum, sname, city, comm * 100, ' % ' FROM Продавцы;Таблицы - это неупорядоченные наборы данных, и выводимые данные по запросу не обязательно появляются в какой-то определенной последовательности. SQL использует предложение ORDER BY, чтобы упорядочивать вывод. Многочисленные столбцы упорядочиваются один внутри другого, также как с GROUP BY, и можно определять сортировку по возрастанию (ASC) или убыванию (DESC ) для каждого столбца. По умолчанию установлена сортировка по возрастанию. Пример 4.20 Вывести таблицу Порядки, отсортированную по номеру заказчика в порядке убывания: SELECT * FROM Порядки ORDER BY cnum DESC;Предложение ORDER BY может использоваться совместно с GROUP BY для упорядочивания групп. Структура запроса в этом случае имеет вид:
SELECT <список выбора> FROM <имя таблицы> [WHERE <предикат>] [GROUP BY <выражение>] [HAVING <предикат>] [ORDER BY <поля>] ;
Пример 4.21