← Назад к вопросам
Что такое оконная функция в SQL? В чем отличие от функции агрегации с группировкой?
2.0 Middle🔥 191 комментариев
#SQL и базы данных
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое оконные функции
Оконная функция (Window Function) в SQL — это функция, которая выполняет вычисления над подмножеством строк (окном) таблицы, сохраняя исходное количество строк в результате. Отличие от агрегирующих функций в том, что она не схлопывает данные в один результат, а применяется к каждой строке отдельно в контексте определённого набора соседних строк.
Синтаксис оконной функции
FUNCTION_NAME(column) OVER (
[PARTITION BY column1, column2, ...]
[ORDER BY column3 ASC|DESC]
[ROWS BETWEEN start AND end]
)
Компоненты:
- PARTITION BY — разделение данных на подмножества (как GROUP BY, но без схлопывания)
- ORDER BY — порядок сортировки строк внутри окна
- ROWS/RANGE — определение границ окна
Основные оконные функции
1. Функции ранжирования
-- ROW_NUMBER() — уникальный номер строки
SELECT
name,
salary,
ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) as rank
FROM employees;
-- RANK() — ранг с пропусками при одинаковых значениях
SELECT
name,
salary,
RANK() OVER (PARTITION BY department ORDER BY salary DESC) as rank
FROM employees;
-- DENSE_RANK() — ранг без пропусков
SELECT
name,
salary,
DENSE_RANK() OVER (PARTITION BY department ORDER BY salary DESC) as rank
FROM employees;
2. Агрегирующие оконные функции
SELECT
name,
salary,
department,
AVG(salary) OVER (PARTITION BY department) as avg_dept_salary,
SUM(salary) OVER (PARTITION BY department) as total_dept_salary,
COUNT(*) OVER (PARTITION BY department) as dept_count
FROM employees;
3. Функции смещения
SELECT
date,
revenue,
LAG(revenue) OVER (ORDER BY date) as prev_day_revenue,
LEAD(revenue) OVER (ORDER BY date) as next_day_revenue,
revenue - LAG(revenue) OVER (ORDER BY date) as growth
FROM daily_sales;
4. Функции относительного положения
SELECT
name,
salary,
FIRST_VALUE(salary) OVER (PARTITION BY department ORDER BY salary DESC) as highest_salary,
LAST_VALUE(salary) OVER (PARTITION BY department ORDER BY salary DESC) as lowest_salary
FROM employees;
GROUP BY vs Window Functions
GROUP BY (агрегация с сжатием)
-- Результат: 3 строки (по одной на отдел)
SELECT
department,
AVG(salary) as avg_salary
FROM employees
GROUP BY department;
Результат:
department | avg_salary
-----------|------------
Sales | 55000
Engineering| 85000
HR | 45000
Window Function (без сжатия)
-- Результат: все строки с добавленной колонкой
SELECT
name,
salary,
department,
AVG(salary) OVER (PARTITION BY department) as avg_salary
FROM employees;
Результат:
name | salary | department | avg_salary
------|--------|------------|----------
Alice | 60000 | Sales | 55000
Bob | 50000 | Sales | 55000
Carol | 90000 | Engineering| 85000
Dave | 80000 | Engineering| 85000
Eve | 45000 | HR | 45000
Практический пример: скользящее среднее
SELECT
date,
revenue,
AVG(revenue) OVER (
ORDER BY date
ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
) as moving_avg_7days,
ROW_NUMBER() OVER (ORDER BY date) as day_number
FROM daily_sales
ORDER BY date;
Это вычисляет среднее выручки за последние 7 дней (включая текущий день) для каждой даты.
Когда использовать
Window Functions лучше когда:
- Нужно сохранить все исходные строки
- Нужны расчёты относительно других строк в наборе (LAG, LEAD)
- Нужно добавить агрегированные значения к каждой строке
- Нужно ранжировать строки внутри групп
GROUP BY лучше когда:
- Нужна полная агрегация данных
- Нужно сжать данные (итоговый отчёт)
- Нужна фильтрация по агрегированным значениям (HAVING)
Оконные функции — мощный инструмент для анализа данных, которые часто используются в реальной практике Data Science для временных рядов, сравнения значений и расчёта метрик.