SQL (9/14)
💻Оконные функции - мощь аналитики в SQL (9/14)
Оконные функции - это особый класс функций в SQL, которые позволяют выполнять вычисления по набору строк, связанных с текущей, без уменьшения числа строк в результате. Это мощный инструмент для аналитика, который помогает решать задачи ранжирования, накопительных сумм, скользящих средних и многое другое, при этом сохраняя детальную информацию по каждой записи.
Типы оконных функций и задачи, которые они решают
Агрегатные оконные функции - аналог агрегатных (SUM, AVG, COUNT) только с возможностью считать по окнам данных, не группируя весь набор строк. Например, подсчёт накопительной суммы или скользящего среднего.
Функции ранжирования - позволяют присваивать строкам ранги в пределах окна. К ним относятся ROW_NUMBER() (присваивает уникальный последовательный номер), RANK() (даёт одинаковый ранг одинаковым значениям, при этом пропускает следующие номера) и DENSE_RANK() (как RANK, но без пропусков).
Функции смещения - LAG() и LEAD() позволяют получить значения предыдущей или следующей строки, что полезно для вычисления разниц, сравнения и анализа трендов.
Примеры наиболее часто используемых оконных функций
Представим таблицу с продажами по клиентам: |customer_id|order_date| amount | |-----------|----------|--------| | 1 |2025-01-01| 100 | | 1 |2025-01-05| 150 | | 2 |2025-01-02| 200 | | 2 |2025-01-03| 50 | | 3 |2025-01-04| 300 | 1. ROW_NUMBER() - уникальный порядковый номер внутри группы
SELECT customer_id, order_date, amount, ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY order_date) AS row_num FROM sales; Результат: |customer_id|order_date| amount | row_num | |-----------|----------|--------|---------| | 1 |2025-01-01| 100 | 1 | | 1 |2025-01-05| 150 | 2 | | 2 |2025-01-02| 200 | 1 | | 2 |2025-01-03| 50 | 2 | | 3 |2025-01-04| 300 | 1 | Полезно, например, чтобы отобрать первый заказ каждого клиента.
2. RANK() и DENSE_RANK() - ранжирование с учётом равных значений
Если у нескольких заказов одинаковая сумма, RANK() даст им одинаковый номер, но с пропусками впереди.
SELECT customer_id, amount, RANK() OVER (PARTITION BY customer_id ORDER BY amount DESC) AS rank FROM sales; Результат (примеры с повторяющимися суммами в данных): | customer_id | amount | rank | |-------------|--------|------| | 1 | 150 | 1 | | 1 | 100 | 2 | | 2 | 200 | 1 | | 2 | 50 | 2 | DENSE_RANK() отличается тем, что пропусков в рангах нет.
3. SUM() OVER - накопительная сумма
Накопительная сумма показывает сумму всех предыдущих значений по определённому окну.
SELECT customer_id, order_date, amount, SUM(amount) OVER (PARTITION BY customer_id ORDER BY order_date) AS cumulative_sum FROM sales; Результат: |customer_id|order_date| amount | cumulative_sum | |-----------|----------|--------|----------------| | 1 |2025-01-01| 100 | 100 | | 1 |2025-01-05| 150 | 250 | | 2 |2025-01-02| 200 | 200 | | 2 |2025-01-03| 50 | 250 | | 3 |2025-01-04| 300 | 300 | Это помогает видеть, как растёт объём продаж со временем у каждого клиента.
Почему они на столько крутые?
Оконные функции совмещают детализацию данных с мощью агрегатов, позволяют решать сложные бизнес-задачи без дополнительных подзапросов и объединений. Они ускоряют разработку, помогают писать понятный и поддерживаемый код и дают аналитикам новый уровень инструментов для исследования данных.
Запомните, даже самый спокойный медведь умеет рычать, когда надо. Берегите голову, берегите данные — и пусть в вашем дне будет немного тишины, ясности и добрых переменных.