1.4Kпросмотров
20 июля 2025 г.
📷 ФотоScore: 1.5K
➡️Оконные функции в SQL — Что такое фреймы простыми словами. 1️⃣Определение:
Фрейм — это диапазон строк, с которыми работает оконная функция внутри окна (OVER (...)). Он позволяет гибко управлять тем, какие строки попадут в расчет. Это важно, когда нужно, например, посчитать кумулятивные значения или сделать «скользящее окно». Синтаксис фрейма:
<функция> OVER ( PARTITION BY ... ORDER BY ... ROWS BETWEEN <граница_начала> AND <граница_конца> -- Строка с фреймом
)
💡Тип фрейма чаще всего: ROWS 2️⃣Типы фреймов:
🔵ROWS — работает с физическим количеством строк Пример:
У нас есть таблица с ежемесячной прибылью компании за год:
month | net_profit |
---------|------------|
Январь | 120 |
Февраль | 90 |
Март | 100 |
Апрель | 130 |
... | ... |
Сентябрь | 80 |
... | ... | Цель — понять, на каком месяце накопленная прибыль превысила 700. Для этого нужна кумулятивная сумма — то есть прибавляем прибыль каждого месяца к предыдущим. Решение при помощи фрейма:
WITH cumulative_profit AS ( SELECT month, net_profit, SUM(net_profit) OVER ( ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS cumulative_sum FROM monthly_profit
)
SELECT month, cumulative_sum
FROM cumulative_profit
WHERE cumulative_sum > 700
LIMIT 1; -- Ограничиваем результат до первого месяца, когда сумма превышает 700
💡Такой фрейм включает все строки от начала до текущей, и для каждой строки рассчитывается сумма. Границы могут быть:
UNBOUNDED PRECEDING — с самого начала
CURRENT ROW — текущая строка
n PRECEDING / FOLLOWING — строк до/после текущей Ещё пример:
ROWS BETWEEN 2 PRECEDING AND 1 FOLLOWING
Скользящее окно из 4 строк: 2 до, текущая, и 1 после. Можно использовать, например, для расчета скользящего среднего:
AVG(net_profit) OVER ( ORDER BY month_number ROWS BETWEEN 2 PRECEDING AND 1 FOLLOWING
) 🔵RANGE — работает с диапазоном значений. Основное отличие от ROWS заключается в том, что акцент делается на самом значении в строке, а не на её расположении в окне. Пример:
SUM(price) OVER ( ORDER BY price RANGE BETWEEN 10 PRECEDING AND 10 FOLLOWING
) 💡Сюда попадут все строки, где price в диапазоне ±10 от текущей. 🔵GROUPS — группирует строки с одинаковыми значениями сортировки (редко используется). Сравнительный пример с ROWS скину в комментарии. Важно знать:
🔵Фреймы работают только с агрегатными функциями (SUM, AVG, MIN, MAX и т.д.) и некоторыми функциями смещения (FIRST_VALUE, LAST_VALUE)
🔵Не работают с ранжирующими функциями (RANK, ROW_NUMBER)
🔵Желательно задавать ORDER BY — без него результат будет непредсказуемым
🔵Если используете PARTITION BY, фрейм работает внутри каждой группы отдельно 😘 Сохраняйте пост и пишите в комментах, если что-то осталось непонятным — разберём вместе!