Ответ
Агрегирующие функции выполняют вычисление над набором строк и возвращают одно результирующее значение. Они часто используются с оператором GROUP BY.
Основные агрегатные функции:
| Функция | Описание | Пример использования |
|---|---|---|
COUNT() |
Подсчитывает количество строк. COUNT(*) считает все строки, COUNT(column) — не-NULL значения. |
SELECT COUNT(*) FROM orders; |
SUM() |
Вычисляет сумму значений числового столбца. | SELECT SUM(amount) FROM payments WHERE status = 'success'; |
AVG() |
Вычисляет среднее арифметическое значений. | SELECT AVG(rating) FROM product_reviews; |
MAX() / MIN() |
Находит максимальное или минимальное значение в столбце. Работают с числами, датами, строками. | SELECT MIN(price), MAX(price) FROM products; |
GROUP_CONCAT() (MySQL) / STRING_AGG() (PostgreSQL) |
Объединяет строковые значения из группы в одну строку с разделителем. | SELECT department_id, GROUP_CONCAT(employee_name) FROM employees GROUP BY department_id; |
Ключевые моменты и пример с GROUP BY:
-- Пример: средний чек и количество заказов по каждому клиенту
SELECT
customer_id,
COUNT(*) AS order_count, -- Количество заказов клиента
AVG(total_amount) AS avg_order, -- Средняя сумма заказа
SUM(total_amount) AS total_spent -- Общая потраченная сумма
FROM orders
WHERE created_at >= '2024-01-01'
GROUP BY customer_id -- Группировка по клиенту
HAVING COUNT(*) > 5; -- Фильтрация по результату агрегации
Важно:
WHEREфильтрует строки до агрегации.HAVINGфильтрует результаты после агрегации (какWHEREдля сгруппированных данных).- Агрегатные функции игнорируют значения
NULL(кромеCOUNT(*)).
Ответ 18+ 🔞
Давайте разберём эту скучную хуйню про агрегаты, но так, чтобы не уснуть на ходу. Представьте, что у вас есть куча записей в таблице — как эти ваши заказы, пользователи, отзывы. И вам надо не просто их вывалить на экран, а посчитать что-то по ним, свести к одному значению. Вот для этого и существуют эти самые агрегатные функции, ёпта.
Основные инструменты для сводок:
| Функция | Что делает, если по-простому | Пример, чтобы не быть мудаком |
|---|---|---|
COUNT() |
Считает, сколько строк. COUNT(*) — вообще все, даже пустые. COUNT(column) — только те, где в колонке не NULL. |
SELECT COUNT(*) FROM orders; — сколько всего заказов, блядь. |
SUM() |
Сумирует значения в числовой колонке. Типа общую выручку посчитать. | SELECT SUM(amount) FROM payments WHERE status = 'success'; — сколько бабла реально пришло, а не отменилось. |
AVG() |
Берёт среднее арифметическое. Все значения складывает и делит на их количество. | SELECT AVG(rating) FROM product_reviews; — средняя оценка товара, чтобы понять, говно он или нет. |
MAX() / MIN() |
Находит самое большое или самое маленькое значение. Работает не только с цифрами, но и с датами, строками. | SELECT MIN(price), MAX(price) FROM products; — от самой дешёвой до самой наглой цены. |
GROUP_CONCAT() (MySQL) / STRING_AGG() (PostgreSQL) |
Склеивает текстовые значения из группы в одну строку через разделитель. Овердохуища полезная штука. | SELECT department_id, GROUP_CONCAT(employee_name) FROM employees GROUP BY department_id; — получаем список всех сотрудников отдела в одной ячейке, чтоб не бегать глазами. |
А теперь самое важное — GROUP BY. Без него это всё просто игрушки.
Вот смотри, обычно ты работаешь с отдельными строками. А GROUP BY говорит: «А давайте, сука, сгруппируем строки по какому-то признаку (по клиенту, по дате, по отделу) и для каждой группы посчитаем агрегаты».
-- Практический пример: что нам нужно знать про каждого клиента?
SELECT
customer_id, -- Группируем по нему
COUNT(*) AS order_count, -- Сколько раз он вообще заказывал
AVG(total_amount) AS avg_order, -- Средний чек, чтоб понять, щедрый он или жмот
SUM(total_amount) AS total_spent -- И сколько всего бабла с него содрали
FROM orders
WHERE created_at >= '2024-01-01' -- Берём заказы только с начала года (фильтр ДО группировки!)
GROUP BY customer_id -- Вот она, магия группировки!
HAVING COUNT(*) > 5; -- А это фильтр ПОСЛЕ группировки. Показываем только тех, кто заказывал больше 5 раз.
Ключевая разница, которую нужно вбить в башку:
WHERE— это страж у ворот. Он отсеивает строки ДО ТОГО, как их начнут группировать и считать. «Ты — заказ 2023 года? Иди нахуй, тебя в расчёт не берём».HAVING— это вышибала уже внутри клуба. Он работает ПОСЛЕ группировки и агрегации. «Ага, вот группа клиентов. Ты, клиент, сделал всего 2 заказа? Мало, братан, не проходишь в наш топ, иди отсюда».HAVINGфильтрует по результатам агрегатных функций (COUNT,SUM,AVG).
И ещё один нюанс, который всех ебёт в начале: агрегатные функции (кроме COUNT(*)) нагло игнорируют значения NULL. Так что если считаешь AVG(score), а у кого-то в score пусто, то этот кто-то просто не попадёт в расчёт.