Window functions в SQL: как считать метрики по группам без боли

Window functions без боли: как считать метрики по группам, ранги и накопления без потери строк и почему это так важно в аналитике и Data Science.

Содержание Следующие статьи
Содержание Window functions в SQL: как считать метрики по группам без боли
  1. Почему оконные функции ощущаются как переход на следующий уровень SQL
  2. Что значит окно в SQL
  3. Чем это отличается от group by
  4. Как показать идею на Python-аналоге

Почему оконные функции ощущаются как переход на следующий уровень SQL

До знакомства с window functions многие задачи решают через `group by`, подзапросы и самодельные join-цепочки. Это работает, но часто делает запросы тяжелыми и нечитаемыми. Оконные функции меняют сам способ мышления: теперь можно считать агрегаты по группе, ранги и накопительные значения, не уничтожая исходные строки. То есть каждая запись сохраняет свою детализацию, но при этом получает контекст своего окна.

Для аналитики и Data Science это особенно полезно, потому что много признаков строится именно так: среднее по пользователю, ранг заказа внутри категории, накопительная сумма, значение предыдущей даты и так далее.

Что значит окно в SQL

Формула: раздел математики — дискретная математика и последовательности
$$ window\_metric_i = f(x_1, \ldots, x_i, \ldots, x_n) $$
Что означает эта формула

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

Что означает каждый символ
  • window\_metric_i — значение метрики для текущей строки i
  • f — агрегирующее правило, например сумма, среднее или ранг
  • x_1 \ldots x_n — строки, попавшие в текущее окно по partition и order

Интуитивно окно — это способ сказать: «посмотри на текущую строку не изолированно, а в контексте других строк из той же группы или последовательности».

Чем это отличается от group by

`group by` схлопывает строки в агрегированную таблицу. Это отлично, когда нам нужен итог по группе. Но если после этого мы хотим вернуть агрегат обратно к каждой строке, начинается лишняя механика. Оконные функции позволяют сразу получить и исходную строку, и агрегатное окружение вокруг нее. За счет этого проще строить признаки и диагностические отчеты.

Например, можно для каждого заказа посчитать средний чек пользователя, ранг заказа по времени и накопительную сумму покупок — и все это в одном табличном представлении.

Как показать идею на Python-аналоге

example.pyPython
import pandas as pd  # создаем таблицу заказов для демонстрации оконной логики

orders = pd.DataFrame({  # задаем пользователя, дату и сумму заказа
    'user_id': [1, 1, 1, 2, 2],  # ключ пользователя
    'day': [1, 3, 5, 2, 4],  # порядок событий во времени
    'amount': [100, 250, 180, 300, 150],  # сумма конкретного заказа
})
orders = orders.sort_values(['user_id', 'day'])  # имитируем order by внутри окна
orders['rank_in_user'] = orders.groupby('user_id').cumcount() + 1  # считаем ранг заказа в истории пользователя
orders['cum_amount'] = orders.groupby('user_id')['amount'].cumsum()  # накапливаем сумму заказов по пользователю
orders['user_mean_amount'] = orders.groupby('user_id')['amount'].transform('mean')  # даем каждой строке средний чек пользователя
print(orders)  # смотрим итоговую таблицу с оконными метриками

После такого примера window functions перестают казаться магией. Становится видно, что они нужны не ради красивого синтаксиса, а ради очень конкретного преимущества: считать контекстные метрики, не теряя строковую детализацию данных.

Что читать дальше

Связанные статьи по этой теме

Canary deployment для моделей: как выкатывать новую версию без лишнего риска Latency в ML API: почему быстрая модель важна не меньше точной Batch inference и real-time inference: как выбирать режим работы модели
Вернуться в блог