Какие основные агрегирующие функции вы знаете в SQL?

Ответ

Агрегирующие функции выполняют вычисление над набором строк и возвращают одно результирующее значение. Они часто используются с оператором 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 пусто, то этот кто-то просто не попадёт в расчёт.