Перейти к содержимому

Как посчитать среднее значение в sql

  • автор:

Функция SQL AVG()

Оператор SQL AVG() — Функция возвращающая среднее значение столбца. Применима только для числовых столбцов!

Функция SQL AVG() имеет следующий синтаксис:

AVG(column_name)

Примеры оператора SQL AVG: Имеется следующая таблица Universities :

ID UniversityName Students Faculties Professores Location Site
1 Perm State National Research University 12400 12 1229 Perm psu.ru
2 Saint Petersburg State University 21300 24 13126 Saint-Petersburg spbu.ru
3 Novosibirsk State University 7200 13 1527 Novosibirsk nsu.ru
4 Moscow State University 35100 39 14358 Moscow msu.ru
5 Higher School of Economics 20335 12 1615 Moscow hse.ru
6 Ural Federal University 57000 19 5640 Yekaterinburg urfu.ru
7 National Research Nuclear University 8600 10 936 Moscow mephi.ru

Пример 1. Используя оператор SQL AVG найти среднее число студентов (Students) всех университетов:

SELECT AVG(Students) FROM Universities

Пример 2. Используя оператор SQL AVG найти среднее число факультетов (Faculties) в университетах Москвы:

SELECT AVG(Faculties) FROM Univetsities WHERE Location = 'Moscow'

Агрегатные функции — Основы SQL

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

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

Функция COUNT

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

SELECT * FROM users;

Запрос вернет нам много строк, но точное их количество мы не знаем. Чтобы это выяснить, можно использовать функцию COUNT — она возвращает количество записей в выборке.

Ответить на вопрос «А сколько записей содержится в таблице users ?» можно с помощью такого запроса:

SELECT COUNT(*) FROM users;

Этот запрос выведет нам ровно одно число — количество строк в запросе. Это равносильно количеству пользователей в нашей базе, потому что в этой таблице хранится информация об уникальных пользователях.

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

Еще в качестве аргумента мы можем передать имя поля. В этом случае функция вернет нам количество строк, в которых поле НЕ равно NULL . Выполним такой запрос:

SELECT COUNT(id) FROM users;

Этот запрос также вернул значение 99 — это количество строк, id которых не равен NULL .

Подадим в качестве аргумента поле email_confirmed :

SELECT COUNT(email_confirmed) FROM users;

Этот запрос вернул 0 , потому что в таблице поле email_confirmed не содержит никаких данных.

Обратите внимание, что COUNT возвращает количество записей в запросе, а не в таблице:

SELECT COUNT(*) FROM users WHERE gender = 'female';

Этот запрос вернет количество девушек среди всех пользователей.

Функция SUM

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

SELECT SUM(spent_minutes) FROM course_reviews;

В этом запросе мы нашли суммарное время, проведенное всеми пользователями на онлайн-курсах.

В качестве аргумента в функцию SUM нужно передать числовое поле. Если передать поле, в котором хранятся строки или даты, то запрос вернет ошибку. Также, не получится передать в функцию символ * , как мы это делали с функцией COUNT :

-- Передадим поле с датами создания — запрос вернет ошибку SELECT SUM(created_at) FROM course_reviews; -- Передадим символ '*' — запрос завершится с ошибкой SELECT SUM(*) FROM course_reviews;

Функция AVG

Чтобы найти среднее арифметическое всех значений, нужно воспользоваться функцией AVG (average — среднее).

В таблице ниже вы увидите, как это происходит:

Работает функция так же как и SUM . В качестве аргумента нужно передать числовое поле.

Найдем среднее время, проведенное пользователем с id = 9 на площадке онлайн-школы:

SELECT AVG(spent_minutes) FROM course_reviews WHERE user_id = 9;

SQL — Урок 11. Итоговые функции, вычисляемые столбцы и представления

Теперь, мы хотим узнать, на какую сумму нам привез товар поставщик «Дом печати» (id=2). Составить такой запрос не так просто. Давайте поразмышляем, как его составить:

1. Сначала надо из таблицы Поставки (incoming) выбрать идентификаторы (id_incoming) тех поставок, которые осуществлялись поставщиком «Дом печати» (id=2):

SELECT id_incoming FROM incoming WHERE id_vendor=2;

2. Теперь из таблицы Журнал поставок (magazine_incoming) надо выбрать товары (id_product) и их количества (quantity), которые осуществлялись в найденных в пункте 1 поставках. То есть запрос из пункта 1 становится вложенным:

SELECT id_product, quantity FROM magazine_incoming WHERE id_incoming=(SELECT id_incoming FROM incoming WHERE id_vendor=2);

3. Теперь нам надо добавить в результирующую таблицу цены на найденные товары, которые хранятся в таблице Цены (prices). То есть нам понадобится объединение таблиц Журнал поставок (magazine_incoming) и Цены (prices) по столбцу id_product:

SELECT magazine_incoming.id_product, magazine_incoming.quantity, prices.price FROM magazine_incoming, prices WHERE magazine_incoming.id_product= prices.id_product AND id_incoming= (SELECT id_incoming FROM incoming WHERE id_vendor=2);

4. В получившейся таблице явно не хватает столбца Сумма, то есть вычисляемого столбца . Возможность создания таких столбцов предусмотрена в MySQL. Для этого надо лишь указать в запросе имя вычисляемого столбца и что он должен вычислять. В нашем примере такой столбец будет называться summa, а вычислять он будет произведение столбцов quantity и price. Название нового столбца отделяется словом AS:

SELECT magazine_incoming.id_product, magazine_incoming.quantity, prices.price, magazine_incoming.quantity*prices.price AS summa FROM magazine_incoming, prices WHERE magazine_incoming.id_product= prices.id_product AND id_incoming= (SELECT id_incoming FROM incoming WHERE id_vendor=2);

5. Отлично, нам осталось лишь просуммировать столбец summa и наконец-то узнаем, на какую сумму нам привез товар поставщик «Дом печати». Синтаксис для использования функции SUM() следущий:

SELECT SUM(имя_столбца) FROM имя_таблицы;

Имя столбца нам известно — summa, а вот имени таблицы у нас нет, так как она является результатом запроса. Что же делать? Для таких случаев в MySQL существуют Представления . Представление — это запрос на выборку, которому присваивается уникальное имя и который можно сохранять в базе данных, для последующего использования.

Синтаксис создания представления следующий:

CREATE VIEW имя_представления AS запрос;
Давайте сохраним наш запрос, как представление с именем report_vendor:

CREATE VIEW report_vendor AS SELECT magazine_incoming.id_product, magazine_incoming.quantity, prices.price, magazine_incoming.quantity*prices.price AS summa FROM magazine_incoming, prices WHERE magazine_incoming.id_product= prices.id_product AND id_incoming= (SELECT id_incoming FROM incoming WHERE id_vendor=2);

6. Вот теперь можно использовать итоговую функцию SUM() :
SELECT SUM(summa) FROM report_vendor;

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

Вычисляемые поля (столбцы)

На примере мы рассмотрели сегодня математическое вычисляемое поле. Здесь хотелось бы добавить, что использовать можно не только операцию умножения (*), но и вычитание (-), и сложение (+), и деление (/). Синтаксис следующий:

SELECT имя_столбца_1, имя_столбца_2, имя_столбца_1*имя_столбца_2 AS имя_вычисляемого_столбца FROM имя_таблицы;

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

CREATE VIEW report_vendor AS SELECT A.id_product, A.quantity, B.price, A.quantity*B.price AS summa FROM magazine_incoming AS A, prices AS B WHERE A.id_product= B.id_product AND id_incoming= (SELECT id_incoming FROM incoming WHERE id_vendor=2);

Согласитесь, что так гораздо короче и понятнее.

Представления

Синтаксис создания представлений мы уже рассматривали. После создания представлений, их можно использовать так же, как таблицы. То есть выполнять запросы к ним, фильтровать и сортировать данные, объединять одни представления с другими. С одной стороны это очень удобный способ хранения частоприменяемых сложных запросов (как в нашем примере).

Но следует помнить, что представления — это не таблицы, то есть они не хранят данные, а лишь извлекают их из других таблиц. Отсюда, во-первых, при изменении данных в таблицах, результаты представления так же будут меняться. А во-вторых, при запросе к представлению происходит поиск необходимых данных, то есть производительность СУБД снижается. Поэтому злоупотреблять ими не стоит.

Научись программировать на Python прямо сейчас!

  • Научись программировать на Python прямо сейчас
  • Бесплатный курс

Если этот сайт оказался вам полезен, пожалуйста, посмотрите другие наши статьи и разделы.

AVG (Transact-SQL)

Эта функция возвращает среднее арифметическое группы значений. Значения NULL она не учитывает.

Синтаксис

AVG ( [ ALL | DISTINCT ] expression ) [ OVER ( [ partition_by_clause ] order_by_clause ) ] 

Сведения о синтаксисе Transact-SQL для SQL Server 2014 (12.x) и более ранних версиях см . в документации по предыдущим версиям.

Аргументы

ВСЕ
Применяет агрегатную функцию ко всем значениям. ALL является параметром по умолчанию.

DISTINCT
Указывает на то, что функция AVG выполняется только для одного уникального экземпляра каждого значения, независимо от того, сколько раз встречается это значение.

выражение
Выражение категории точного числового или приблизительного числового типа данных, за исключением типа данных bit. Агрегатные функции и вложенные запросы не допускаются.

OVER ( [ partition_by_clause ] order_by_clause)
partition_by_clause делит результирующий набор, полученный с помощью предложения FROM, на секции, к которым применяется функция. Если этот параметр не указан, функция обрабатывает все строки результирующего набора запроса как отдельные группы. order_by_clause определяет логический порядок, в котором выполняется операция. Аргумент order_by_clause является обязательным. Дополнительные сведения см. в статье Предложение OVER (Transact-SQL).

Типы возвращаемых данных

Тип возвращаемого значения определяется типом вычисленного результата выражения.

Результат выражения Возвращаемый тип
tinyint int
smallint int
int int
bigint bigint
Категория decimal (p, s) decimal(38, max(s,6))
Категории money и smallmoney money
Категории float и real float

Замечания

Если тип данных expression является типом данных-псевдонимом, тип возвращаемого значения также является типом данных-псевдонимом. Однако если базовый тип данных типа данных-псевдонима может повышаться, например из tinyint в int, возвращаемое значение будет иметь повышенный тип данных, а не тип данных-псевдоним.

Функция AVG () вычисляет среднее арифметическое набора значений, выполняя деление суммы этих значений на число значений, не равных NULL. Если сумма превышает максимальное значение для типа данных возвращаемого значения, AVG() возвратит ошибку.

AVG — это детерминированная функция, если она используется без предложений OVER и ORDER BY. Она не детерминирована при использовании с предложениями OVER и ORDER BY. Дополнительные сведения см. в разделе Deterministic and Nondeterministic Functions.

Примеры

А. Использование функций SUM и AVG для вычислений

В этом примере вычисляется среднее время отпуска и сумма часов больничного отпуска, которые использовали вице-президенты adventure Works Cycles. Каждая из этих агрегатных функций создает одно сводное значение для всех извлеченных строк. В примере используется база данных AdventureWorks2022.

SELECT AVG(VacationHours)AS 'Average vacation hours', SUM(SickLeaveHours) AS 'Total sick leave hours' FROM HumanResources.Employee WHERE JobTitle LIKE 'Vice President%'; 
Average vacation hours Total sick leave hours ---------------------- ---------------------- 25 97 (1 row(s) affected) 

B. Использование функций SUM и AVG в предложении GROUP BY

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

SELECT TerritoryID, AVG(Bonus)as 'Average bonus', SUM(SalesYTD) as 'YTD sales' FROM Sales.SalesPerson GROUP BY TerritoryID; GO 
TerritoryID Average Bonus YTD Sales ----------- --------------------- --------------------- NULL 0.00 1252127.9471 1 4133.3333 4502152.2674 2 4100.00 3763178.1787 3 2500.00 3189418.3662 4 2775.00 6709904.1666 5 6700.00 2315185.611 6 2750.00 4058260.1825 7 985.00 3121616.3202 8 75.00 1827066.7118 9 5650.00 1421810.9242 10 5150.00 4116871.2277 (11 row(s) affected) 

C. Использование функции AVG с ключевым словом DISTINCT

Эта инструкция возвращает среднюю цену на продукты в базе данных AdventureWorks2022. При использовании DISTINCT в расчете учитываются только уникальные значения.

SELECT AVG(DISTINCT ListPrice) FROM Production.Product; 
------------------------------ 437.4042 (1 row(s) affected) 

D. Использование функции AVG без ключевого слова DISTINCT

Без DISTINCT AVG функция находит среднюю цену списка всех продуктов в таблице в Product базе данных AdventureWorks2022, включая все повторяющиеся значения.

SELECT AVG(ListPrice) FROM Production.Product; 
------------------------------ 438.6662 (1 row(s) affected) 

Д. Использование предложения OVER

В следующем примере функция AVG используется с предложением OVER для предоставления скользящей средней ежегодной продажи для каждой территории в таблице базы Sales.SalesPerson данных AdventureWorks2022. Данные секционируются по TerritoryID и логически сортируются по SalesYTD . Это означает, что функция AVG вычисляется для каждой территории на основании объема продаж за год. Обратите внимание, что в TerritoryID 1 для продаж за 2005 год используются две строки, в которых представлены два менеджера по продажам с показателями за этот год. После расчета среднего значения продаж для двух данных строк в вычисление включается третья строка, представляющая продажи за 2006 год.

SELECT BusinessEntityID, TerritoryID ,DATEPART(yy,ModifiedDate) AS SalesYear ,CONVERT(VARCHAR(20),SalesYTD,1) AS SalesYTD ,CONVERT(VARCHAR(20),AVG(SalesYTD) OVER (PARTITION BY TerritoryID ORDER BY DATEPART(yy,ModifiedDate) ),1) AS MovingAvg ,CONVERT(VARCHAR(20),SUM(SalesYTD) OVER (PARTITION BY TerritoryID ORDER BY DATEPART(yy,ModifiedDate) ),1) AS CumulativeTotal FROM Sales.SalesPerson WHERE TerritoryID IS NULL OR TerritoryID < 5 ORDER BY TerritoryID,SalesYear; 
BusinessEntityID TerritoryID SalesYear SalesYTD MovingAvg CumulativeTotal ---------------- ----------- ----------- -------------------- -------------------- -------------------- 274 NULL 2005 559,697.56 559,697.56 559,697.56 287 NULL 2006 519,905.93 539,801.75 1,079,603.50 285 NULL 2007 172,524.45 417,375.98 1,252,127.95 283 1 2005 1,573,012.94 1,462,795.04 2,925,590.07 280 1 2005 1,352,577.13 1,462,795.04 2,925,590.07 284 1 2006 1,576,562.20 1,500,717.42 4,502,152.27 275 2 2005 3,763,178.18 3,763,178.18 3,763,178.18 277 3 2005 3,189,418.37 3,189,418.37 3,189,418.37 276 4 2005 4,251,368.55 3,354,952.08 6,709,904.17 281 4 2005 2,458,535.62 3,354,952.08 6,709,904.17 (10 row(s) affected) 

В этом примере предложение OVER не включает в себя предложение PARTITION BY. Это означает, что функция будет применяться для всех строк, возвращаемых запросом. Предложение ORDER BY, указанное в предложении OVER, определяет логический порядок применения функции AVG. Запрос возвращает скользящее среднее значение продаж за год для всех территорий, указанных в предложении WHERE. Предложение ORDER BY, указанное в инструкции SELECT, определяет порядок, в котором эта инструкция отображает строки запроса.

SELECT BusinessEntityID, TerritoryID ,DATEPART(yy,ModifiedDate) AS SalesYear ,CONVERT(VARCHAR(20),SalesYTD,1) AS SalesYTD ,CONVERT(VARCHAR(20),AVG(SalesYTD) OVER (ORDER BY DATEPART(yy,ModifiedDate) ),1) AS MovingAvg ,CONVERT(VARCHAR(20),SUM(SalesYTD) OVER (ORDER BY DATEPART(yy,ModifiedDate) ),1) AS CumulativeTotal FROM Sales.SalesPerson WHERE TerritoryID IS NULL OR TerritoryID < 5 ORDER BY SalesYear; 
BusinessEntityID TerritoryID SalesYear SalesYTD MovingAvg CumulativeTotal ---------------- ----------- ----------- -------------------- -------------------- -------------------- 274 NULL 2005 559,697.56 2,449,684.05 17,147,788.35 275 2 2005 3,763,178.18 2,449,684.05 17,147,788.35 276 4 2005 4,251,368.55 2,449,684.05 17,147,788.35 277 3 2005 3,189,418.37 2,449,684.05 17,147,788.35 280 1 2005 1,352,577.13 2,449,684.05 17,147,788.35 281 4 2005 2,458,535.62 2,449,684.05 17,147,788.35 283 1 2005 1,573,012.94 2,449,684.05 17,147,788.35 284 1 2006 1,576,562.20 2,138,250.72 19,244,256.47 287 NULL 2006 519,905.93 2,138,250.72 19,244,256.47 285 NULL 2007 172,524.45 1,941,678.09 19,416,780.93 (10 row(s) affected) 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *