Какие агрегатные функции знаешь в SQL?

Ответ

Агрегатные функции выполняют вычисление на наборе строк и возвращают одно значение. Они часто используются с предложением GROUP BY.

Основные агрегатные функции (стандарт SQL):

  1. COUNT() - подсчитывает количество строк.

    • COUNT(*) считает все строки, включая NULL.
    • COUNT(column) считает только не-NULL значения в указанном столбце.
      -- Общее количество заказов
      SELECT COUNT(*) AS total_orders FROM orders;
      -- Количество заказов с указанным идентификатором клиента
      SELECT COUNT(customer_id) FROM orders;
      -- Количество уникальных клиентов, сделавших заказы
      SELECT COUNT(DISTINCT customer_id) FROM orders;
  2. SUM() - вычисляет сумму значений в числовом столбце.

    SELECT SUM(quantity * unit_price) AS total_revenue FROM order_details;
  3. AVG() - вычисляет среднее арифметическое значений.

    SELECT AVG(salary) AS average_salary FROM employees WHERE department = 'Engineering';
  4. MIN() / MAX() - находят минимальное и максимальное значение.

    SELECT MIN(price) AS cheapest, MAX(price) AS most_expensive FROM products;

Важные особенности и работа с GROUP BY:

  • Агрегатные функции игнорируют NULL значения (кроме COUNT(*)).
  • GROUP BY группирует строки с одинаковыми значениями, и агрегация применяется к каждой группе отдельно.
  • HAVING используется для фильтрации результатов после агрегации, в отличие от WHERE, который фильтрует строки до.
-- Пример: средний чек по каждому клиенту, у кого было больше 5 заказов
SELECT
    customer_id,
    COUNT(*) AS order_count,
    AVG(total_amount) AS avg_order_value
FROM orders
GROUP BY customer_id
HAVING COUNT(*) > 5; -- Фильтрация по результату агрегации

Специфичные для СУБД функции (примеры):

  • PostgreSQL/MySQL: STRING_AGG() / GROUP_CONCAT() - объединяет строковые значения из группы в одну строку с разделителем.
  • Статистические: STDDEV() (стандартное отклонение), VARIANCE() (дисперсия).
  • Для работы с битами: BIT_AND(), BIT_OR().

Ответ 18+ 🔞

Э, слушай, давай разжёвывать про эти ваши агрегатные функции, а то народ путается постоянно, как будто впервые слышит. Это ж элементарно, ёпта! Представь, что у тебя куча записей в таблице — овердохуища строк. А тебе надо не всё подряд, а какую-то одну циферку на всю эту толпу получить: сумму, среднее, количество. Вот для этого они и нужны, эти функции. Без них как без рук, реально.

Основные-то, классические, их все знают, но всё равно напомню, а то подозрение ебать чувствую, что кто-то нихуя не помнит.

  1. COUNT() — просто считает, сколько штук. Но тут есть хитрая жопа: COUNT(*) посчитает вообще все строки, даже если там в колонках одни NULL. А вот COUNT(имя_колонки) — этот хитрый уёбок проигнорирует все NULL в этой колонке и посчитает только нормальные значения. И ещё есть COUNT(DISTINCT ...) — чтобы уникальных клиентов посчитать, а не общее число заказов. Чувствуешь разницу? А то некоторые путают, терпения ноль ебать.

    -- Сколько всего заказов, даже пустых? Все!
    SELECT COUNT(*) AS total_orders FROM orders;
    -- А сколько заказов, где customer_id не NULL? Только такие!
    SELECT COUNT(customer_id) FROM orders;
    -- А сколько разных клиентов вообще заказывало? Вот это полезно!
    SELECT COUNT(DISTINCT customer_id) FROM orders;
  2. SUM() — ну, тут всё ясно, э бошка думай. Берёт все числа в колонке и плюсует. Главное, чтобы колонка была числовой, а то будет тебе хиросима и нигерсраки с ошибками.

    SELECT SUM(quantity * unit_price) AS total_revenue FROM order_details;
  3. AVG() — среднее арифметическое. Складывает всё и делит на количество. Тоже NULL игнорирует, умная функция.

    SELECT AVG(salary) AS average_salary FROM employees WHERE department = 'Engineering';
  4. MIN() / MAX() — нашли самого маленького и самого большого в стаде. Всё просто.

А теперь, внимание, самый сок — GROUP BY. Вот где народ реально охуевает и путает WHERE с HAVING. Слушай сюда.

Без GROUP BY функция считает по ВСЕЙ таблице разом — одна циферка на выходе. А вот если ты хочешь, чтобы считалось отдельно для каждой группы (например, для каждого клиента, для каждого отдела), то ты пишешь GROUP BY customer_id. И тогда COUNT(*) посчитает заказы не все скопом, а для КАЖДОГО клиента свою циферку. Удивление пиздец, да?

И вот главный подвох, манда с ушами для новичков: WHERE работает ДО того, как строки сгруппировали и посчитали. А HAVING — это уже фильтр ПОСЛЕ группировки и агрегации. То есть в HAVING ты можешь писать условия типа «покажи только тех клиентов, у которых COUNT(*) > 5». В WHERE так не выйдет, он этих агрегатов ещё не знает!

-- Давай на живом: смотрим на каждого клиента
SELECT
    customer_id,
    COUNT(*) AS order_count, -- сколько раз он заказывал
    AVG(total_amount) AS avg_order_value -- и средний его чек
FROM orders
GROUP BY customer_id -- группируем по клиенту, а не валим всё в кучу
HAVING COUNT(*) > 5; -- И оставляем только заядлых покупателей, которые заказывали больше 5 раз

Ну и напоследок, есть ещё специфичные штуки в разных базах. В PostgreSQL и MySQL, например, есть STRING_AGG() или GROUP_CONCAT()ебушки-воробушки, удобнейшая вещь! Может все имена в группе склеить в одну строку через запятую. Есть ещё статистические STDDEV() (среднеквадратичное) — для умных расчётов, или битовые BIT_AND() — но это уже для совсем извращенцев, полупидоров от математики.

Короче, суть в чём: агрегатные функции — это твой молоток и отвёртка в SQL. Без них нихуя не соберёшь. Главное — не путай, когда фильтровать ДО (WHERE), а когда ПОСЛЕ (HAVING). Всё остальное — дело практики.