Стандартные оконные функции
Синтаксис
PARTITION BY- определяет, как разбить результирующий набор на группы.ORDER BY- определяет порядок строк внутри группы при вычислении aggregate_function.ROWS,RANGEилиGROUPS- определяет границы рамки окна, в пределах которой вычисляется aggregate_function.ROWSсчитает физические строки,RANGE— значенияORDER BY, аGROUPS— группы равноправных строк (строки с одинаковым ключомORDER BY).WINDOW- позволяет нескольким выражениям использовать одно и то же определение окна.
Функции, доступные только как оконные функции
lagInFrame, leadInFrame и nonNegativeDerivative — расширения ClickHouse.
Примеры
Нумерация строк
Функции агрегации
Партиционирование по столбцу
Границы рамки окна
Рамка GROUPS
GROUPS считает целые группы равных строк — наборы строк с одинаковым ключом ORDER BY — а не физические строки (ROWS) или значения ORDER BY (RANGE). N PRECEDING и N FOLLOWING отсчитывают N групп равных строк до и после группы равных строк текущей строки, при этом каждая включённая группа учитывается целиком.
В приведённом ниже запросе используются одинаковые границы 1 PRECEDING AND 1 FOLLOWING для рамок ROWS, RANGE и GROUPS. Столбец order содержит повторяющиеся и непоследовательные значения, поэтому три режима охватывают разные строки:
ROWSсчитает физические строки, поэтому рамка окна включает не более трёх соседних строк: текущую и по одной с каждой стороны.RANGEсчитает значенияorder, поэтому1 PRECEDINGи1 FOLLOWINGохватывают строки, чьё значениеorderотличается от значения текущей строки не более чем на 1. При разрывах в 10 ни одна соседняя строка не попадает в рамку, поэтому она содержит только строки с тем же значениемorder, что и у текущей строки.GROUPSсчитает группы равных строк, поэтому1 PRECEDINGи1 FOLLOWINGвсегда полностью включают соседние группы независимо от разрывов между значениямиorder.
Примеры из практики
Максимальная/общая зарплата по отделам
Нарастающий итог
Скользящее среднее (по 3 строкам)
Скользящее среднее (за 10 секунд)
Скользящее среднее (за 10 дней)
Range и ORDER BY toDate(ts) мы формируем рамку окна размером 10 единиц, и благодаря toDate(ts) этой единицей является день.