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

Агрегатные функции SQL помогают получать итоги по данным таблицы. Например, посчитать количество товаров, найти среднюю цену или сложить цены товаров в наборе.

COUNT считает строки, SUM складывает значения, AVG вычисляет среднее, а MIN и MAX находят минимум и максимум.

В примерах будем работать с таблицей конфет candy. Цена указана в поле price, наличие начинки — в поле filling.

id name filling price
1 Plutonian Praline true 30
2 Explosive Comet true 60
3 Universal Harmony false 20
4 Pluto's Tears false 40
5 Mint Vortex false 40
7 Plutonic Cream false 70
10 Pluto Mystery true 90

Таблица candy

COUNT — количество строк

При включённом фильтре «С начинкой» каталог показывает три позиции. Проверим количество позиций и сколько из них имеют цену.

COUNT(*) Считает все строки, которые прошли отбор.
COUNT(price) Считает строки, в которых указана цена.

После AS можно задать заголовок столбца результата. Здесь candies — количество конфет, prices — количество указанных цен.

SELECT COUNT(*) AS candies,
       COUNT(price) AS prices
FROM candy
WHERE filling = true;
candies prices
3 3

У всех трёх конфет с начинкой указана цена. Если убрать WHERE, счётчик покажет все семь позиций каталога.

SUM, AVG, MIN и MAX — расчёт цен

Рассчитаем сумму цен конфет с начинкой, а также их среднюю, минимальную и максимальную цену.

SUM Складывает цены выбранных конфет.
AVG Вычисляет среднее арифметическое цен.
MIN Находит наименьшую цену.
MAX Находит наибольшую цену.
SELECT SUM(price) AS total,
       AVG(price) AS mean_price,
       MIN(price) AS lowest,
       MAX(price) AS highest
FROM candy
WHERE filling = true;
total mean_price lowest highest
180 60 30 90

Цены конфет с начинкой — 30, 60 и 90. Вместе это 180, в среднем 180 / 3 = 60 за конфету. Крайние значения — 30 и 90.

Группировка с GROUP BY

В отчёте два итога — для конфет с начинкой и без неё. Чтобы сверить оба одним запросом, сгруппируем строки по filling.

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

В этом примере filling указан дважды. В GROUP BY он разделяет конфеты по наличию начинки, а в SELECT показывает, к какой группе относится сумма.

SELECT filling, SUM(price) AS total
FROM candy
GROUP BY filling;
filling total
true 180
false 170

Три конфеты с начинкой стоят вместе 180, четыре без начинки — 170. Сумма двух строк отчёта должна совпасть с суммой по всему каталогу.

Отбор групп с HAVING

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

Перечислите в GROUP BY оба поля через запятую. Теперь каждая группа — одно сочетание filling и price. COUNT(*) покажет, сколько в ней строк.

HAVING отбирает группы по условию. В этом примере оставим только группы, в которых две конфеты или больше.

SELECT filling, price, COUNT(*) AS qty
FROM candy
GROUP BY filling, price
HAVING COUNT(*) > 1;
filling price qty
false 40 2

У Pluto's Tears и Mint Vortex цена 40, обе конфеты без начинки. Для других сочетаний в таблице есть только по одной строке.

WHERE отбирает строки до группировки. HAVING отбирает группы после расчёта итогов.

Условие WHERE COUNT(*) > 1 вызовет ошибку: в момент отбора строк размер группы ещё неизвестен. Для проверки цены отдельной конфеты подойдёт WHERE price > 40, а для проверки средней цены группы — HAVING AVG(price) > 40.

Задача

Магазин формирует наборы конфет. Проверьте расчёт их стоимости по таблице candy.

Правила формирования наборов:

  • Конфеты с начинкой и без начинки собирают в отдельные наборы.
  • В набор включают только конфеты ценой от 30 до 70 включительно.
  • Набор поступает в продажу, если в нём не менее трёх конфет.

Напишите SQL-запрос, который рассчитает стоимость набора, допущенного к продаже.

tester_today Учебная БД
⌘ / Ctrl + Enter
Результат запроса
Готов к выполнению
Задача доступна премиум пользователям!

Открой доступ, чтобы заниматься без ограничений.

Полный доступ ко всем практическим задачам
Проверка ответов
Неограниченное количество попыток