Агрегатни функции: COUNT, SUM, AVG
Накратко: Агрегатните функции COUNT, SUM, AVG, MIN и MAX свиват много редове в един резултат: брой, сума, средна, най-малка или най-голяма стойност.
Проблем
Отчетът в понеделник
Всеки понеделник собственичката пита едни и същи неща. Колко клиенти имаме? От колко града са? Колко пари са минали през магазина? Кой е най-скъпият продукт?
Досега заявките връщаха редове. Тук трябва едно число от много редове. Да ги броиш на ръка не става: утре редовете ще са хиляди.
Идеята
COUNT: колко са
COUNT(*) брои редовете:
Двайсет реда влизат, един ред излиза. Функция, която свива много редове в една стойност, се казва обобщаваща функция (aggregate function).
COUNT има още два вида. COUNT(колона) брои само редовете, в които колоната не е NULL. COUNT(DISTINCT колона) брои различните стойности:
20 клиенти, 19 с град (Борис е без град) и 6 различни града.
Пробвай
Колко са изчерпани
Управителят не иска имената, а само броя: колко продукта са с наличност 0? Полето показва кои са. Свий го до едно число.
Решение
SELECT COUNT(*) FROM products WHERE stock = 0;SELECT COUNT(*) FROM products WHERE stock = 0. Два продукта. WHERE минава първо и оставя двата реда, а COUNT(*) ги брои.
Идеята
SUM, AVG, MIN, MAX
Другите четири функции работят със стойностите в колоната:
SUM: сборът;AVG: средното;MINиMAX: най-малката и най-голямата стойност.
Оборотът е сборът на всеки ред от поръчка: количество по цена.
1 963,50 €. Внимание: тук са и редовете на отказаните поръчки. Кои поръчки са отказани, пише в orders, а сумите са в order_items. Двете таблици ще свързваме в следващия модул, с JOIN.
Най-евтиният, най-скъпият и средната цена на продуктите:
MIN и MAX работят и с текст, и с дати. Първата и последната поръчка:
Пробвай
Оценката на кафето
Кафето на зърна (product_id = 17) получи лош отзив. Колко отзива има то и каква е средната му оценка?
Решение
SELECT COUNT(*), AVG(rating)
FROM reviews
WHERE product_id = 17;SELECT COUNT(*), AVG(rating) FROM reviews WHERE product_id = 17. Три отзива и средна оценка 3,33: две добри (5 и 4) и една единица.
Виж го
Един ред, дори когато няма нищо
Обобщение без групи връща винаги един ред. Три реда на поръчка 8 стават един:
А ако през WHERE не мине нито един ред? Отзиви от октомври 2026 г. още няма:
Пак един ред: COUNT дава 0, а AVG дава NULL. Няма от какво да се смята средно. Същото правят SUM, MIN и MAX. В отчета NULL изглежда като празна клетка, затова при нужда го смени с COALESCE(SUM(...), 0).
Виж го
AVG прескача NULL
Като COUNT(колона), и SUM, AVG, MIN и MAX прескачат NULL. При AVG това променя резултата: делиш не на всички редове, а на тези със стойност.
Каква е средната наличност? А средната наличност на продуктите, които ги има? NULLIF(stock, 0) прави нулите NULL:
Когато пишеш AVG върху колона с NULL, питай се: празните трябва ли да броят като нула? Ако да, AVG(COALESCE(колона, 0)). Ако не, AVG(колона) вече го прави.
Упражнение
Две справки
1. Доставчикът на кафе пита колко бройки кафе на зърна (product_id = 17) сме продали и за колко пари.
Бройките и парите от кафето на зърна:
Решение
SELECT SUM(quantity), SUM(quantity * unit_price)
FROM order_items
WHERE product_id = 17;SELECT SUM(quantity), SUM(quantity * unit_price) FROM order_items WHERE product_id = 17. 10 пакета за 149 €. COUNT(*) тук щеше да даде 3: толкова реда, а не бройки.
2. Колко поръчки са доставени и на колко различни клиенти?
Доставените поръчки и различните клиенти в тях:
Решение
SELECT COUNT(*), COUNT(DISTINCT customer_id)
FROM orders
WHERE status = 'delivered';SELECT COUNT(*), COUNT(DISTINCT customer_id) FROM orders WHERE status = 'delivered'. 21 поръчки на 11 клиенти: някои клиенти са получили повече от една.
Тест
Провери се
Свързани уроци
Раздел „Свързани уроци“- Нужно отпреди: NULL: няма стойност · ORDER BY, LIMIT и DISTINCT · Сметки в заявката · CASE и липсващите стойности
- Продължава в: GROUP BY: отчет по групи · HAVING: условие за групите · Редът на изпълнение на заявката · LEFT JOIN: и редовете без двойка
- Задачи по темата: Обобщаване