Рамка окна
Набор строк внутри секции, которым оперирует оконная функция, называется рамкой окна (кадры окна).Рамка окна определяет, какие строки следует учитывать для текущей строки при оценке оконной функции.
Рамка окна состоит из трёх частей: единица (unit), начальная граница и конечная граница.В качестве единицы может быть использовано ключевые слова RANGE
или ROWS
, которые определяют, каким образом будут работать границы окна.Границы окна определяются следующими выражениями:
-
<expr> PRECEDING
-
<expr> FOLLOWING
-
CURRENT ROW
Предложения ROWS
и RANGE
требуют, чтобы было указано предложение ORDER BY
.Если предложение ORDER BY
отсутствует, то для агрегатных функций рамка окна состоит из всех строк в разбиении.Если задано предложение ORDER BY
, то по умолчанию рамка окна состоит из всех строк, от начала разбиения до текущей строки, плюс любые следующие строки, которые равны текущей строке в соответствии с предложением ORDER BY
,т.е. RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
.
Предложение ROWS
ограничивает строки внутри секции путем указания фиксированного числа строк, предшествующих или следующих после текущей строки.В качестве альтернативы предложение RANGE
логически ограничивает строки внутри секции путем указания диапазона значений в отношении к значению текущей строки.Предшествующие и последующие строки определяются на основании порядка, заданного в предложении ORDER BY
.
-
Если рамка окна задаётся с помощью предложения
RANGE
, то предложениеORDER BY
может содержать только одно выражение и выражение должно быть числового типа,DATE
,TIME
илиTIMESTAMP
.Для<expr> PRECEDING
выражение expr вычитается из выражения вORDER BY
, а для<expr> FOLLOWING
— добавляется.ДляCURRENT ROW
выражение вORDER BY
используется как есть.Затем все строки (внутри секции) между границам считаются частью результирующей рамки окна.
-
Если рамка окна задаётся с помощью предложения
ROWS
, то на предложениеORDER BY
не накладывается ограничений на количество и типы выражений.В этом случае фраза<expr> PRECEDING
указывает количество строк предшествующее текущей строке, соответственно фраза<expr> FOLLOWING
указывает количество строк после текущей строки.
UNBOUNDED PRECEDING
и UNBOUNDED FOLLOWING
работают одинаково для предложений ROWS
и RANGE
.Фраза UNBOUNDED PRECEDING
указывает, что окно начинается с первой строки секции. UNBOUNDED PRECEDING
может быть указано только как начальная точка окна.Фраза UNBOUNDED FOLLOWING
указывает, что окно заканчивается последней строкой секции. UNBOUNDED FOLLOWING
может быть указано только как конечная точка окна.
Фраза CURRENT ROW
указывает, что окно начинается или заканчивается на текущей строке при использовании совместно с предложением ROWS
,или что окно заканчивается на текущем значении при использовании с предложением RANGE
.CURRENT ROW
может быть задана и как начальная, и как конечная точка.
Предложение BETWEEN
используется совместно с ключевым словом ROWS
или RANGE
для указания нижней (начальной) или верхней (конечной) граничной точки окна.Верхняя граница не может быть меньше нижней границы.
Note
|
Если указана только начальная точка окна, то конечной точкой окна считается |
Некоторые оконные функции игнорируют выражение рамки:
-
ROW_NUMBER
,LAG
иLEAD
всегда работают какROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
. -
DENSE_RANK
,RANK
,PERCENT_RANK
иCUME_DIST
работают какRANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
. -
FIRST_VALUE
,LAST_VALUE
иNTH_VALUE
работают на рамке, ноRANGE
работает идентичноROWS
.
Таким образом, предложения ROWS
и RANGE
позволяют довольно гибко настроить размер плавающего окна.Чаще всего встречаются следующие варианты:
-
Нижняя граница фиксирована (совпадает с первой строкой упорядоченной группы), а верхняя граница ползёт (совпадает с текущей строкой упорядоченной группы). В этом случае получаем нарастающий итог (кумулятивный агрегат). В этом случае размер окна меняется (расширяется в одну сторону) и само окно движется за счёт расширения. Возможна и обратная ситуация, когда нижняя граница ползёт, а верхняя зафиксирована. В этом случае окно будет сужаться.
-
Если верхняя и нижняя границы фиксированы относительно текущей строки, например 1 строка до текущей и 2 после текущей, то получаем скользящий агрегат. В этом случае размер окна фиксирован, а само окно скользит.