14.20.1 Описания оконных функций
В этом разделе описываются оконные функции, которые для каждой строки запроса выполняют вычисления, используя строки, относящиеся к этой строке. Большинство агрегатных функций также могут использоваться как оконные функции; см. Раздел 14.19.1, «Описания агрегатных функций».
Сведения о применении и примерах использования оконных функций, а также определения терминов, таких как фраза OVER, окно, разбиение, фрейм и соседние строки, см. в Разделе 14.20.2, «Понятия и синтаксис оконных функций».
Таблица 14.30 Оконные функции
| Имя | Описание |
|---|---|
CUME_DIST() | Значение кумулятивного распределения |
DENSE_RANK() | Ранг текущей строки в её разбиении без пробелов |
FIRST_VALUE() | Значение аргумента из первой строки оконного фрейма |
LAG() | Значение аргумента из строки, отстающей от текущей в рамках разбиения |
LAST_VALUE() | Значение аргумента из последней строки оконного фрейма |
LEAD() | Значение аргумента из строки, опережающей текущую в рамках разбиения |
NTH_VALUE() | Значение аргумента из N-ой строки оконного фрейма |
NTILE() | Номер корзины текущей строки в её разбиении |
PERCENT_RANK() | Значение процентильного ранга |
RANK() | Ранг текущей строки в её разбиении с пробелами |
ROW_NUMBER() | Номер текущей строки в её разбиении |
В следующих описаниях функций over_clause представляет собой OVER-фрагмент, описанный в Разделе 14.20.2, «Понятия и синтаксис оконных функций». Некоторые оконные функции допускают использование фрагмента null_treatment, который определяет, как обрабатывать NULL значения при вычислении результатов. Этот фрагмент является необязательным. Он является частью стандарта SQL, но реализация MySQL допускает только RESPECT NULLS (что также является значением по умолчанию). Это означает, что NULL значения учитываются при вычислении результатов. IGNORE NULLS обрабатывается, но приводит к ошибке.
-
CUME_DIST()over_clauseВозвращает кумулятивное распределение значения внутри группы значений; то есть процент значений раздела, меньших или равных значению в текущей строке. Это представляет собой количество строк, предшествующих или равных текущей строке в порядке окна раздела окна, деленное на общее количество строк в разделе окна. Значения возврата находятся в диапазоне от 0 до 1.
Эта функция должна использоваться с
ORDER BYдля сортировки строк раздела в желаемом порядке. БезORDER BYвсе строки являются равными и имеют значениеN/N= 1, гдеN— размер раздела.over_clauseописана в разделе 14.20.2, «Концепции и синтаксис функций окна».Следующий запрос показывает для набора значений в столбце
valзначениеCUME_DIST()для каждой строки, а также значение процентильного ранга, возвращаемое аналогичной функциейPERCENT_RANK(). Для справки запрос также отображает номера строк с помощьюROW_NUMBER():mysql>
SELECTval,ROW_NUMBER() OVER w AS 'row_number',CUME_DIST() OVER w AS 'cume_dist',PERCENT_RANK() OVER w AS 'percent_rank'FROM numbersWINDOW w AS (ORDER BY val);+------+------------+--------------------+--------------+ | val | row_number | cume_dist | percent_rank | +------+------------+--------------------+--------------+ | 1 | 1 | 0.2222222222222222 | 0 | | 1 | 2 | 0.2222222222222222 | 0 | | 2 | 3 | 0.3333333333333333 | 0.25 | | 3 | 4 | 0.6666666666666666 | 0.375 | | 3 | 5 | 0.6666666666666666 | 0.375 | | 3 | 6 | 0.6666666666666666 | 0.375 | | 4 | 7 | 0.8888888888888888 | 0.75 | | 4 | 8 | 0.8888888888888888 | 0.75 | | 5 | 9 | 1 | 1 | +------+------------+--------------------+--------------+ -
DENSE_RANK()over_clauseВозвращает ранг текущей строки в ее разделе без пробелов. Равные значения считаются ничьей и получают один и тот же ранг. Эта функция присваивает последовательные ранги группам равных значений; в результате группы размером более одного не создают несмежные номера ранга. Пример см. в описании функции
RANK().Эта функция должна использоваться с
ORDER BYдля сортировки строк раздела в желаемом порядке. БезORDER BYвсе строки являются равными.over_clauseописана в разделе 14.20.2, «Концепции и синтаксис функций окна». -
FIRST_VALUE([expr)null_treatment]over_clauseВозвращает значение
exprиз первой строки фрейма окна.over_clauseописана в разделе 14.20.2, «Концепции и синтаксис функций окна».null_treatmentописана во введении к разделу.Следующий запрос демонстрирует
FIRST_VALUE(),LAST_VALUE()и два случаяNTH_VALUE():mysql>
SELECTtime, subject, val,FIRST_VALUE(val) OVER w AS 'first',LAST_VALUE(val) OVER w AS 'last',NTH_VALUE(val, 2) OVER w AS 'second',NTH_VALUE(val, 4) OVER w AS 'fourth'FROM observationsWINDOW w AS (PARTITION BY subject ORDER BY timeROWS UNBOUNDED PRECEDING);+----------+---------+------+-------+------+--------+--------+ | time | subject | val | first | last | second | fourth | +----------+---------+------+-------+------+--------+--------+ | 07:00:00 | st113 | 10 | 10 | 10 | NULL | NULL | | 07:15:00 | st113 | 9 | 10 | 9 | 9 | NULL | | 07:30:00 | st113 | 25 | 10 | 25 | 9 | NULL | | 07:45:00 | st113 | 20 | 10 | 20 | 9 | 20 | | 07:00:00 | xh458 | 0 | 0 | 0 | NULL | NULL | | 07:15:00 | xh458 | 10 | 0 | 10 | 10 | NULL | | 07:30:00 | xh458 | 5 | 0 | 5 | 10 | NULL | | 07:45:00 | xh458 | 30 | 0 | 30 | 10 | 30 | | 08:00:00 | xh458 | 25 | 0 | 25 | 10 | 30 | +----------+---------+------+-------+------+--------+--------+Каждая функция использует строки в текущем фрейме, который, согласно определению окна, показанному, простирается от первой строки раздела до текущей строки. Для вызовов
NTH_VALUE()текущий фрейм не всегда включает запрашиваемую строку; в таких случаях возвращаемое значение —NULL. -
LAG([expr[,N[,default]])null_treatment]over_clauseВозвращает значение
exprиз строки, отстающей (предшествующей) текущей строке наNстрок в пределах ее раздела. Если такой строки нет, возвращаемое значение —default. Например, еслиNравно 3, возвращаемое значение —defaultдля первых трех строк. ЕслиNилиdefaultотсутствуют, значения по умолчанию равны 1 иNULLсоответственно.Nдолжно быть целочисленной неотрицательной константой. ЕслиNравно 0,exprвычисляется для текущей строки.Nне может бытьNULLи должно быть целым числом в диапазоне от0до263включительно в любом из следующих форматов:целочисленная константа-литерал
маркер позиционного параметра (
?)пользовательская переменная
локальная переменная в хранимой процедуре
over_clauseописана в разделе 14.20.2, «Концепции и синтаксис функций окна».null_treatmentописана во введении к разделу.LAG()(и аналогичная функцияLEAD()) часто используются для вычисления различий между строками. Следующий запрос показывает набор упорядоченных по времени наблюдений и для каждого из них значенияLAG()иLEAD()из смежных строк, а также разницы между текущей и смежными строками:mysql>
SELECTt, val,LAG(val) OVER w AS 'lag',LEAD(val) OVER w AS 'lead',val - LAG(val) OVER w AS 'lag diff',val - LEAD(val) OVER w AS 'lead diff'FROM seriesWINDOW w AS (ORDER BY t);+----------+------+------+------+----------+-----------+ | t | val | lag | lead | lag diff | lead diff | +----------+------+------+------+----------+-----------+ | 12:00:00 | 100 | NULL | 125 | NULL | -25 | | 13:00:00 | 125 | 100 | 132 | 25 | -7 | | 14:00:00 | 132 | 125 | 145 | 7 | -13 | | 15:00:00 | 145 | 132 | 140 | 13 | 5 | | 16:00:00 | 140 | 145 | 150 | -5 | -10 | | 17:00:00 | 150 | 140 | 200 | 10 | -50 | | 18:00:00 | 200 | 150 | NULL | 50 | NULL | +----------+------+------+------+----------+-----------+В примере вызовы
LAG()иLEAD()используют значения по умолчаниюNиdefaultсоответственно, равные 1 иNULL.Первая строка показывает, что происходит, когда для
LAG()нет предыдущей строки: функция возвращает значениеdefault(в данном случаеNULL). Последняя строка показывает то же самое, когда дляLEAD()нет следующей строки.LAG()иLEAD()также служат для вычисления сумм, а не разностей. Рассмотрим этот набор данных, который содержит первые несколько чисел ряда Фибоначчи:mysql>
SELECT n FROM fib ORDER BY n;+------+ | n | +------+ | 1 | | 1 | | 2 | | 3 | | 5 | | 8 | +------+Следующий запрос показывает значения
LAG()иLEAD()для строк, примыкающих к текущей строке. Он также использует эти функции для добавления к значению текущей строки значений из предшествующей и последующей строк. Эффект заключается в генерации следующего числа в ряду Фибоначчи и следующего за ним числа:mysql>
SELECTn,LAG(n, 1, 0) OVER w AS 'lag',LEAD(n, 1, 0) OVER w AS 'lead',n + LAG(n, 1, 0) OVER w AS 'next_n',n + LEAD(n, 1, 0) OVER w AS 'next_next_n'FROM fibWINDOW w AS (ORDER BY n);+------+------+------+--------+-------------+ | n | lag | lead | next_n | next_next_n | +------+------+------+--------+-------------+ | 1 | 0 | 1 | 1 | 2 | | 1 | 1 | 2 | 2 | 3 | | 2 | 1 | 3 | 3 | 5 | | 3 | 2 | 5 | 5 | 8 | | 5 | 3 | 8 | 8 | 13 | | 8 | 5 | 0 | 13 | 8 | +------+------+------+--------+-------------+Один из способов сгенерировать начальный набор чисел Фибоначчи — использовать рекурсивное общее выражение таблицы. Пример см. в генерации ряда Фибоначчи.
Для аргумента строк этой функции нельзя использовать отрицательное значение.
-
LAST_VALUE([expr)null_treatment]over_clauseВозвращает значение
exprиз последней строки фрейма окна.over_clauseописана в разделе 14.20.2, «Концепции и синтаксис функций окна».null_treatmentописана во введении к разделу.Пример см. в описании функции
FIRST_VALUE().
-
LEAD([expr[,N[,default]])null_treatment]over_clauseВозвращает значение
exprиз строки, предшествующей (следующей) текущей строке наNстрок в пределах своего раздела. Если такой строки нет, возвращаетсяdefault. Например, еслиNравно 3, возвращается значениеdefaultдля последних трех строк. ЕслиNилиdefaultотсутствуют, по умолчанию используются значения 1 иNULLсоответственно.Nдолжно быть целочисленной неотрицательной константой. ЕслиNравно 0, значениеexprвычисляется для текущей строки.Nне может бытьNULLи должно быть целым числом в диапазоне от0до263включительно, в любом из следующих форматов:целочисленная константа без знака
маркер позиционного параметра (
?)пользовательская переменная
локальная переменная в хранимой процедуре
over_clauseописывается в разделе 14.20.2, «Функции окон и синтаксис».null_treatmentописывается в начале раздела.Пример см. в описании функции
LAG().Использование отрицательного значения для аргумента rows этой функции запрещено.
-
NTH_VALUE([expr,N)from_first_last] [null_treatment]over_clauseВозвращает значение
exprизN-й строки фрейма окна. Если такой строки нет, возвращаетсяNULL.Nдолжно быть положительной целочисленной константой.from_first_lastявляется частью стандарта SQL, но реализация MySQL допускает толькоFROM FIRST(что также является значением по умолчанию). Это означает, что вычисления начинаются с первой строки окна.FROM LASTпарсится, но приводит к ошибке. Чтобы получить тот же эффект, что иFROM LAST(начало вычислений с последней строки окна), используйтеORDER BYдля сортировки в обратном порядке.over_clauseописывается в разделе 14.20.2, «Функции окон и синтаксис».null_treatmentописывается в начале раздела.Пример см. в описании функции
FIRST_VALUE().Нельзя использовать
NULLдля аргумента строки этой функции. -
NTILE(N)over_clauseРазделяет раздел на
Nгрупп (корзин), присваивает каждой строке в разделе номер своей корзины и возвращает номер корзины текущей строки в пределах ее раздела. Например, еслиNравно 4,NTILE()разделяет строки на четыре корзины. ЕслиNравно 100,NTILE()разделяет строки на 100 корзин.Nдолжно быть положительной целочисленной константой. Значения номера корзины находятся в диапазоне от 1 доN.Nне может бытьNULLи должно быть целым числом в диапазоне от0до263включительно, в любом из следующих форматов:целочисленная константа без знака
маркер позиционного параметра (
?)пользовательская переменная
локальная переменная в хранимой процедуре
Эту функцию следует использовать с
ORDER BY, чтобы отсортировать строки раздела в нужном порядке.over_clauseописывается в разделе 14.20.2, «Функции окон и синтаксис».В следующем запросе показаны для набора значений в столбце
valпроцентильные значения, полученные в результате деления строк на две или четыре группы. Для справки запрос также отображает номера строк, используяROW_NUMBER():mysql>
SELECTval,ROW_NUMBER() OVER w AS 'row_number',NTILE(2) OVER w AS 'ntile2',NTILE(4) OVER w AS 'ntile4'FROM numbersWINDOW w AS (ORDER BY val);+------+------------+--------+--------+ | val | row_number | ntile2 | ntile4 | +------+------------+--------+--------+ | 1 | 1 | 1 | 1 | | 1 | 2 | 1 | 1 | | 2 | 3 | 1 | 1 | | 3 | 4 | 1 | 2 | | 3 | 5 | 1 | 2 | | 3 | 6 | 2 | 3 | | 4 | 7 | 2 | 3 | | 4 | 8 | 2 | 4 | | 5 | 9 | 2 | 4 | +------+------------+--------+--------+Конструкт
NTILE(NULL)запрещен. -
PERCENT_RANK()over_clauseВозвращает процент значений в разделе, меньших значения в текущей строке, исключая наибольшее значение. Значения возврата находятся в диапазоне от 0 до 1 и представляют собой относительный ранг строки, вычисленный по следующей формуле, где
rank— ранг строки, аrows— количество строк раздела:(
rank- 1) / (rows- 1)Эту функцию следует использовать с
ORDER BY, чтобы отсортировать строки раздела в нужном порядке. БезORDER BYвсе строки являются равнозначными.over_clauseописывается в разделе 14.20.2, «Функции окон и синтаксис».Пример см. в описании функции
CUME_DIST(). -
RANK()over_clauseВозвращает ранг текущей строки в пределах ее раздела с разрывами. Равнозначные строки считаются ничьей и получают один и тот же ранг. Эта функция не присваивает последовательные ранги группам равных значений, если такие группы существуют; результатом являются несмежные номера рангов.
Эту функцию следует использовать с
ORDER BY, чтобы отсортировать строки раздела в нужном порядке. БезORDER BYвсе строки считаются равнозначными.over_clauseописывается в разделе 14.20.2, «Функции окон и синтаксис».Следующий запрос демонстрирует разницу между
RANK(), которая генерирует ранги с разрывами, иDENSE_RANK(), которая генерирует ранги без разрывов. В запросе показаны значения рангов для каждого элемента набора значений в столбцеval, содержащем некоторые дубликаты.RANK()присваивает дубликатам (равнозначным строкам) одинаковое значение ранга, а следующее большее значение имеет ранг, больший на количество дубликатов минус один.DENSE_RANK()также присваивает дубликатам одинаковое значение ранга, но следующее большее значение имеет ранг, больший на единицу. Для справки запрос также отображает номера строк, используяROW_NUMBER():mysql>
SELECTval,ROW_NUMBER() OVER w AS 'row_number',RANK() OVER w AS 'rank',DENSE_RANK() OVER w AS 'dense_rank'FROM numbersWINDOW w AS (ORDER BY val);+------+------------+------+------------+ | val | row_number | rank | dense_rank | +------+------------+------+------------+ | 1 | 1 | 1 | 1 | | 1 | 2 | 1 | 1 | | 2 | 3 | 3 | 2 | | 3 | 4 | 4 | 3 | | 3 | 5 | 4 | 3 | | 3 | 6 | 4 | 3 | | 4 | 7 | 7 | 4 | | 4 | 8 | 7 | 4 | | 5 | 9 | 9 | 5 | +------+------------+------+------------+ -
ROW_NUMBER()over_clauseВозвращает номер текущей строки в пределах ее раздела. Номера строк находятся в диапазоне от 1 до количества строк раздела.
ORDER BYвлияет на порядок нумерации строк. БезORDER BYнумерация строк не детерминирована.ROW_NUMBER()присваивает равнозначным строкам разные номера строк. Чтобы присвоить равнозначным строкам одно и то же значение, используйтеRANK()илиDENSE_RANK(). Пример см. в описании функцииRANK().over_clauseописывается в разделе 14.20.2, «Функции окон и синтаксис».
© 2025 Oracle
Licensed under the GPLv2 License.