Все статьи

Оконные функции SQL — примеры и объяснения

2026-03-0415 мин чтения

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

Что такое оконная функция?

Обычная агрегатная функция (SUM, COUNT) с GROUP BY возвращает одну строку на группу. Оконная функция вычисляет значение для каждой строки, используя «окно» — набор связанных строк.

SELECT name, department, salary,
  AVG(salary) OVER (PARTITION BY department) AS dept_avg
FROM employees;

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

Синтаксис OVER()

функция() OVER (
  [PARTITION BY столбец]   -- разбиение на группы
  [ORDER BY столбец]       -- порядок внутри группы
  [ROWS/RANGE frame]       -- границы окна
)

ROW_NUMBER, RANK, DENSE_RANK

ROW_NUMBER() — уникальный номер строки в окне:

SELECT name, salary,
  ROW_NUMBER() OVER (ORDER BY salary DESC) AS rn
FROM employees;

RANK() — ранг с пропусками при одинаковых значениях (1, 2, 2, 4).

DENSE_RANK() — ранг без пропусков (1, 2, 2, 3).

LAG и LEAD — доступ к соседним строкам

SELECT date, revenue,
  LAG(revenue) OVER (ORDER BY date) AS prev_day,
  revenue - LAG(revenue) OVER (ORDER BY date) AS growth
FROM daily_sales;

LAG(column, N) — значение N строк назад. LEAD(column, N) — N строк вперёд.

Накопительная сумма (Running Total)

SELECT date, amount,
  SUM(amount) OVER (ORDER BY date) AS running_total
FROM transactions;

Скользящее среднее (Moving Average)

SELECT date, revenue,
  AVG(revenue) OVER (
    ORDER BY date
    ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
  ) AS moving_avg_7d
FROM daily_sales;

NTILE — разбиение на группы

SELECT name, salary,
  NTILE(4) OVER (ORDER BY salary) AS quartile
FROM employees;

Разбивает строки на N равных групп. Полезно для перцентилей и квартилей.

FIRST_VALUE, LAST_VALUE

SELECT name, department, salary,
  FIRST_VALUE(name) OVER (
    PARTITION BY department ORDER BY salary DESC
  ) AS top_earner
FROM employees;

Практические задачи

  • Топ-3 сотрудника по зарплате в каждом отделе — ROW_NUMBER + PARTITION BY
  • Разница с предыдущим месяцем — LAG
  • Накопительный процент — SUM OVER / SUM общий × 100
  • Медиана — PERCENTILE_CONT(0.5) WITHIN GROUP

Практикуйте SQL прямо сейчас — 500+ задач с мгновенной проверкой

Начать бесплатно