ROWS считает физические строки. GROUPS считает группы строк с одинаковым значением ORDER BY.SELECT price,
count(*) OVER (
ORDER BY price
GROUPS BETWEEN 1 PRECEDING AND 1 FOLLOWING
)
FROM products;
Если по одной цене находится 50 товаров, вся эта пачка считается одной группой. Поэтому можно строить окна относительно соседних значений, не вычисляя
dense_rank() и не добавляя ещё один уровень запроса.Ещё интереснее
EXCLUDE, который можно использовать прямо внутри оконного фрейма:SELECT id,
avg(score) OVER (
ORDER BY created_at
ROWS BETWEEN 10 PRECEDING AND 10 FOLLOWING
EXCLUDE CURRENT ROW
) AS neighbors_avg
FROM measurements;
Среднее здесь считается по соседним строкам, но текущая строка автоматически исключается.
SELECT price,
sum(amount) OVER (
ORDER BY price
GROUPS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
EXCLUDE GROUP
)
FROM sales;
EXCLUDE GROUP исключит из расчёта всю текущую peer-группу, а не только одну строку.🔥
GROUPS + EXCLUDE позволяют описывать сложные окна непосредственно в OVER, где обычно появляются dense_rank(), дополнительные CTE и self join.➡️ SQL Ready | #совет
