theory_03__OVER.sql

Занятие 36SQL112 строк

← К репозиторию занятия · 09__window_functions/theory_03__OVER.sql

/* Внутри конструкции OVER() в SQL могут быть несколько компонентов,
которые определяют, как будет работать оконная функция. Возможные элементы включают:

    PARTITION BY — Разделение на группы (или окна).
    ORDER BY — Определение порядка строк внутри окна.
    ROWS или RANGE — Определение диапазона строк относительно текущей строки в окне
		(например, для функций скользящего среднего или кумулятивных сумм).

Вот возможные варианты использования этих элементов:
1. Пустое OVER()

	Если OVER() не содержит никаких параметров, функция применяется ко всем строкам сразу:*/

SELECT first_name, last_name, salary,
	SUM(salary) OVER () AS total_salary
FROM hr.employees;

/*
2. PARTITION BY

Разделяет строки на группы (разделы), и функция будет применяться отдельно к каждой группе:*/

SELECT
	first_name, last_name, salary, department_id,
	SUM(salary) OVER (PARTITION BY department_id) AS dept_total_salary
FROM hr.employees;

/*
3. ORDER BY

	Задает порядок строк внутри окна, и в зависимости от функции результаты
	будут вычисляться с учетом этого порядка:*/

SELECT
	first_name, last_name, salary, department_id,
	RANK() OVER (ORDER BY salary DESC) AS rank_
FROM hr.employees;

/*
4. PARTITION BY + ORDER BY

	Объединение PARTITION BY и ORDER BY используется для того, чтобы применить функцию
    к разделам данных и одновременно задать порядок внутри каждого раздела:*/

SELECT
	first_name, last_name, salary, department_id,
	RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS dept_rank
FROM hr.employees;

/*
5. ROWS или RANGE

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

ROWS работает с конкретными строками, относительно текущей строки:*/

SELECT
	first_name, last_name, salary, department_id,
	SUM(salary) OVER (ORDER BY salary ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS moving_sum
FROM hr.employees;

/*Здесь скользящая сумма считается для текущей строки, одной строки до нее и одной строки после.

RANGE работает с диапазоном значений:*/

SELECT
	first_name, last_name, salary, department_id,
	SUM(salary) OVER (ORDER BY salary RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS cumulative_sum
FROM employees;

/*Здесь кумулятивная сумма подсчитывается от первой строки до текущей строки,
основываясь на значениях, а не на количестве строк.


Полный список элементов, которые могут быть внутри OVER():

    PARTITION BY — разделение на группы.
    ORDER BY — порядок строк.
    ROWS — диапазон строк относительно текущей строки.
    RANGE — диапазон значений относительно текущей строки.
    GROUPS (в некоторых диалектах SQL) — другой способ ограничения диапазона для работы с группами строк.

Примеры сложных комбинаций:

    С PARTITION BY, ORDER BY, и диапазоном ROWS:*/

SELECT
	first_name, last_name, salary, department_id,
	SUM(salary) OVER (PARTITION BY department ORDER BY salary ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS sliding_sum
FROM hr.employees;

/*Здесь сумма зарплат считается для текущей строки и двух предыдущих строк,
но внутри каждого департамента.

С PARTITION BY, ORDER BY, и диапазоном RANGE:*/

SELECT
	first_name, last_name, salary, department_id,
	SUM(salary) OVER (PARTITION BY department_id ORDER BY salary RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS cumulative_salary
FROM hr.employees;

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


Важные моменты:

    PARTITION BY разделяет данные, а ORDER BY задает порядок.
    ROWS и RANGE уточняют диапазон строк или значений для более тонкого управления окнами.*/