На первый взгляд может показаться, что в SQL уже есть всё для анализа данных: GROUP BY, агрегаты, подзапросы... Но это только начало. Добро пожаловать в мир оконных функций — мощного инструмента, который позволяет работать с данными построчно, сохраняя весь контекст.
Оконные функции позволяют делать вычисления — сумму, среднее, ранги и другие — по «окну» строк, не сворачивая данные. Это значит, что в отличие от обычных агрегатных функций (SUM(), AVG(), COUNT()), вы получаете и результат, и детали в каждой строке.
Представьте, что вы хотите посчитать накопительный доход по заказам. С GROUP BY вы бы потеряли конкретные заказы — осталась бы только сумма. А с оконной функцией вы добавите результат прямо к каждой строке, не теряя ничего.
Оконные функции особенно удобны, потому что они не уничтожают данные: каждая строка остаётся на месте, а результаты вычислений просто добавляются в новые столбцы. Это позволяет выполнять сложную аналитику без подзапросов и громоздких конструкций — всё делается прямо внутри одного запроса. Такие функции идеально подходят для задач вроде ранжирования, вычисления скользящих средних или сравнения значений между строками. Код остаётся читаемым, а результат — точным.
Когда это особенно полезно:
- Рейтинг сотрудников, продавцов, продуктов — кто на каком месте.
- Временные ряды — как что-то менялось по дням или неделям.
- Продажи и финансы — сколько накопилось на каждом шаге, какие заказы выше среднего, кто входит в топ-25%.
Где применяются оконные функции
В любой области, где важен контекст, а не только итог:
- отчёты по продажам;
- анализ клиентского поведения;
- построение графиков с накопительными метриками;
- сегментация данных (например, по квартилям);
- расчёт отклонений и трендов.
Они — настоящая находка для аналитиков, работающих с SQL каждый день. рассмотрим несколько примеров из реального мира, где оконные функции могут стать вашим спасением.
Пример 1: Ранжирование данных
Представьте, у вас есть список студентов с их оценками за экзамен. Вы хотите присвоить каждому студенту его позицию в классе. С помощью оконных функций это становится элементарно. Например, функции RANK() или ROW_NUMBER() помогут справиться с этой задачей.
Пример 2: Анализ временных данных
А что, если нужно изучить, как доходы компании менялись по месяцам? Вам нужна накопительная сумма доходов. Используя оконную функцию SUM() с определённым окном, вы легко можете получить этот результат.
Пример 3: Квантили и разбиение на группы
Разбить данные на равные группы (например, по доходам) для сегментации клиентов? Здесь на помощь придёт функция NTILE(). Давайте узнаем, кто из клиентов в топ-25%, а кто внизу рейтинга.
Как это выглядит?
Оконная функция просто добавляет результат в итоговый набор данных:
SELECT
student_id,
grade,
RANK() OVER (ORDER BY grade DESC) AS rank
FROM
students;
Тут мы получаем таблицу, где у каждого студента есть его уникальный ранг по оценке.
Простая аналогия
Представьте, что вы на пробежке с группой друзей. Каждый бежит со своей скоростью, но вы хотите знать, какое место вы занимаете в забеге прямо сейчас. Вместо того чтобы остановить всех и составить таблицу лидеров (как это делает GROUP BY), вы просто смотрите на бегущих вокруг и определяете свой текущий рейтинг.
Вот это и есть оконная функция: она не останавливает забег, не разбивает всех по группам — она просто добавляет информацию, сохраняя движение и детали. Каждый продолжает бежать, но теперь у вас есть дополнительная аналитика — например, сколько человек впереди, какой у вас темп по сравнению со средним и т.п.
Преимущества перед традиционными подходами
Рассмотрим классическую задачу: подсчёт ранга продажников по доходу. Есть два подхода:
Без оконных функций. Вам нужно сделать подзапрос или даже несколько подзапросов, чтобы сначала отсортировать данные, затем пронумеровать их. Это не только длинно, но и тяжело читается.
С оконными функциями. Всего один запрос с красивым и понятным синтаксисом, и результат уже у вас. Например:
SELECT
seller_id,
revenue,
RANK() OVER (PARTITION BY region ORDER BY revenue DESC) AS rank_in_region
FROM
sales;
Этот запрос сразу разделяет продавцов по регионам и нумерует их в порядке убывания дохода.
Реальный пример
Теперь представьте, что вы аналитик и анализируете данные по продажам. Вам нужно узнать:
- суммарные доходы за каждый месяц,
- как изменился доход по сравнению с предыдущим месяцем,
- ранжировать регионы по общему доходу.
Всё это можно сделать с использованием оконных функций и даже в одном запросе. Но это уже тема для следующих лекций.
Теперь, вооружившись базовыми знаниями об оконных функциях, вы готовы перейти к их синтаксису и увидеть силу функций ROW_NUMBER(), RANK(), DENSE_RANK() и NTILE(). Переходим к следующей лекции!
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ