- Учимся применять оконные функции
- Принцип работы
- Синтаксис
- PARTITION BY
- ORDER BY
- ROWS или RANGE
- Виды функций
- Агрегатные функции
- Ранжирующие функции
- Функции смещения
- Аналитические функции
- Кейс. Модели атрибуции
- Первый клик
- С учетом давности взаимодействий
- RankMe MySQL
- #1 Dangerous707
- Функция RANK в MySQL
- Введение в функцию RANK() в MySQL
- Пример функции RANK() в MySQL
- Функция RANK() в MySQL с примером CTE
Учимся применять оконные функции
Оконные функции — это мощнейший инструмент аналитика, который с легкостью помогает решать множество задач.
Если вам нужно произвести вычисление над заданным набором строк, объединенных каким-то одним признаком, например идентификатором клиента, вам на помощь придут именно они.
Можно сравнить их с агрегатными функциями, но, в отличие от обычной агрегатной функции, при использовании оконной функции несколько строк не группируются в одну, а продолжают существовать отдельно. При этом результаты работы оконных функций просто добавляются к результирующей выборке как еще одно поле. Этот функционал очень полезен для построения аналитических отчетов, расчета скользящего среднего и нарастающих итогов, а также для расчетов различных моделей атрибуции.
Принцип работы
У вас может возникнуть вопрос – «Что значит оконные?»
При обычном запросе, все множество строк обрабатывается как бы единым «цельным куском», для которого считаются агрегаты. А при использовании оконных функций, запрос делится на части (окна) и уже для каждой из отдельных частей считаются свои агрегаты.
Синтаксис
Окно определяется с помощью обязательной инструкции OVER(). Давайте рассмотрим синтаксис этой инструкции:
Теперь разберем как поведет себя множество строк при использовании того или иного ключевого слова функции. А тренироваться будем на простой табличке содержащей дату, канал с которого пришел пользователь и количество конверсий:
Откроем окно при помощи OVER() и просуммируем столбец «Conversions»:
Мы использовали инструкцию OVER() без предложений. В таком варианте окном будет весь набор данных и никакая сортировка не применяется. Появился новый столбец «Sum» и для каждой строки выводится одно и то же значение 14. Это сквозная сумма всех значений колонки «Conversions».
PARTITION BY
Теперь применим инструкцию PARTITION BY, которая определяет столбец, по которому будет производиться группировка и является ключевой в разделении набора строк на окна:
Инструкция PARTITION BY сгруппировала строки по полю «Date». Теперь для каждой группы рассчитывается своя сумма значений столбца «Conversions».
ORDER BY
Попробуем отсортировать значения внутри окна при помощи ORDER BY:
К предложению PARTITION BY добавилось ORDER BY по полю «Medium». Таким образом мы указали, что хотим видеть сумму не всех значений в окне, а для каждого значения «Conversions» сумму со всеми предыдущими. То есть мы посчитали нарастающий итог.
ROWS или RANGE
Инструкция ROWS позволяет ограничить строки в окне, указывая фиксированное количество строк, предшествующих или следующих за текущей.
Инструкция RANGE, в отличие от ROWS, работает не со строками, а с диапазоном строк в инструкции ORDER BY. То есть под одной строкой для RANGE могут пониматься несколько физических строк одинаковых по рангу.
Обе инструкции ROWS и RANGE всегда используются вместе с ORDER BY.
В выражении для ограничения строк ROWS или RANGE также можно использовать следующие ключевые слова:
- UNBOUNDED PRECEDING — указывает, что окно начинается с первой строки группы;
- UNBOUNDED FOLLOWING – с помощью данной инструкции можно указать, что окно заканчивается на последней строке группы;
- CURRENT ROW – инструкция указывает, что окно начинается или заканчивается на текущей строке;
- BETWEEN«граница окна» AND «граница окна» — указывает нижнюю и верхнюю границу окна;
- «Значение»PRECEDING – определяет число строк перед текущей строкой (не допускается в предложении RANGE).;
- «Значение»FOLLOWING — определяет число строк после текущей строки (не допускается в предложении RANGE).
Разберем на примере:
В данном случае сумма рассчитывается по текущей и следующей ячейке в окне. А последняя строка в окне имеет то же значение, что и столбец «Conversions», потому что больше не с чем складывать.
Комбинируя ключевые слова, вы можете подогнать диапазон работы оконной функции под вашу специфическую задачу.
Виды функций
Оконные функции можно подразделить на следующие группы:
- Агрегатные функции;
- Ранжирующие функции;
- Функции смещения;
- Аналитические функции.
В одной инструкции SELECT с одним предложением FROM можно использовать сразу несколько оконных функций. Давайте подробно разберем каждую группу и пройдемся по основным функциям.
Агрегатные функции
Агрегатные функции – это функции, которые выполняют на наборе данных арифметические вычисления и возвращают итоговое значение.
- SUM – возвращает сумму значений в столбце;
- COUNT — вычисляет количество значений в столбце (значения NULL не учитываются);
- AVG — определяет среднее значение в столбце;
- MAX — определяет максимальное значение в столбце;
- MIN — определяет минимальное значение в столбце.
Пример использования агрегатных функций с оконной инструкцией OVER:
Ранжирующие функции
Ранжирующие функции – это функции, которые ранжируют значение для каждой строки в окне. Например, их можно использовать для того, чтобы присвоить порядковый номер строке или составить рейтинг.
- ROW_NUMBER – функция возвращает номер строки и используется для нумерации;
- RANK — функция возвращает ранг каждой строки. В данном случае значения уже анализируются и, в случае нахождения одинаковых, возвращает одинаковый ранг с пропуском следующего значения;
- DENSE_RANK — функция возвращает ранг каждой строки. Но в отличие от функции RANK, она для одинаковых значений возвращает ранг, не пропуская следующий;
- NTILE – это функция, которая позволяет определить к какой группе относится текущая строка. Количество групп задается в скобках.
Функции смещения
Функции смещения – это функции, которые позволяют перемещаться и обращаться к разным строкам в окне, относительно текущей строки, а также обращаться к значениям в начале или в конце окна.
- LAG илиLEAD – функция LAG обращается к данным из предыдущей строки окна, а LEAD к данным из следующей строки. Функцию можно использовать для того, чтобы сравнивать текущее значение строки с предыдущим или следующим. Имеет три параметра: столбец, значение которого необходимо вернуть, количество строк для смещения (по умолчанию 1), значение, которое необходимо вернуть если после смещения возвращается значение NULL;
- FIRST_VALUE или LAST_VALUE — с помощью функции можно получить первое и последнее значение в окне. В качестве параметра принимает столбец, значение которого необходимо вернуть.
Аналитические функции
Аналитические функции — это функции которые возвращают информацию о распределении данных и используются для статистического анализа.
- CUME_DIST — вычисляет интегральное распределение (относительное положение) значений в окне;
- PERCENT_RANK — вычисляет относительный ранг строки в окне;
- PERCENTILE_CONT — вычисляет процентиль на основе постоянного распределения значения столбца. В качестве параметра принимает процентиль, который необходимо вычислить (в этой статье я рассказываю как посчитать медиану, благодаря этой функции);
- PERCENTILE_DISC — вычисляет определенный процентиль для отсортированных значений в наборе данных. В качестве параметра принимает процентиль, который необходимо вычислить.
Важно! У функций PERCENTILE_CONT и PERCENTILE_DISC, столбец, по которому будет происходить сортировка, указывается с помощью ключевого слова WITHIN GROUP.
Кейс. Модели атрибуции
Благодаря модели атрибуции можно обоснованно оценить вклад каждого канала в достижение конверсии. Давайте попробуем посчитать две разных модели атрибуции с помощью оконных функций.
У нас есть таблица с id посетителя (им может быть Client ID, номер телефона и тп.), датами и количеством посещений сайта, а также с информацией о достигнутых конверсиях.
Первый клик
В Google Analytics стандартной моделью атрибуции является последний непрямой клик. И в данном случае 100% ценности конверсии присваивается последнему каналу в цепочке взаимодействий.
Попробуем посчитать модель по первому взаимодействию, когда 100% ценности конверсии присваивается первому каналу в цепочке при помощи функции FIRST_VALUE.
Рядом со столбцом «Medium» появился новый столбец «First_Click», в котором указан канал в первый раз приведший посетителя к нам на сайт и вся ценность зачтена данному каналу.
Произведем агрегацию и получим отчет.
С учетом давности взаимодействий
В этом случае работает правило: чем ближе к конверсии находится точка взаимодействия, тем более ценной она считается. Попробуем рассчитать эту модель при помощи функции DENSE_RANK.
Рядом со столбцом «Medium» появился новый столбец «Ranks», в котором указан ранг каждой строки в зависимости от близости к дате конверсии.
Теперь используем этот запрос для того, чтобы распределить ценность равную 1 (100%) по всем точкам на пути к конверсии.
Рядом со столбцом «Medium» появился новый столбец «Time_Decay» с распределенной ценностью.
И теперь, если сделать агрегацию, можно увидеть как распределилась ценность по каналам.
Из получившегося отчета видно, что самым весомым каналом является канал «cpc», а канал «cpa», который был бы исключен при применении стандартной модели атрибуции, тоже получил свою долю при распределении ценности.
Источник
RankMe MySQL
#1 Dangerous707
Привет всем! Есть проблема.
Есть 2 сервера. Один на MyArena, другой на другом хостинге. На обоих серверах стоит статистика RankMe. Скрипт Web-статистики установлен на Web-хостинге MyArena. База данных одна и та же прописана на обоих серверах. IP сервера второго хоста добавлен в удалённый доступ на Web’е MyArena. Сначала всё работало нормально. Вчера зашёл на второй сервер и заметил, что перестала реагировать команда rank. Остальные команды плагина (top, session и т.д.) работают. Пробовал переимпортировать таблицу БД.. переустановить плагин на другую версию и на ту же самую.. не получается ничего.
Для особо «умных» остряков — гуглил! (Точнее не гуглил, ибо предпочитаю яндекс) — ничего путного не нашёл. База данных везде прописана ВЕРНО. В web-части я слаб к сожалению. Надеюсь, найдётся человек, который мне поможет. Если есть желание, пишите в ЛС, обсудим.
L 11/15/2016 — 23:06:20: [SM] [0] Line 1275, rankme/cmds.inc::SQL_RankCallback()
Заранее, спасибо хотя бы за обращённое внимание!
Источник
Функция RANK в MySQL
Обратите внимание, что MySQL поддерживает функцию RANK() и другие оконные функции начиная с версии 8.0
Введение в функцию RANK() в MySQL
Функция RANK() присваивает ранг для каждой строки в пределах раздела результирующего набора. Ранг строки определяется одним плюс количество рангов, которые предшествуют ему.
Ниже показан синтаксис функции RANK():
В этом синтаксисе:
В отличие от функции ROW_NUMBER(), функция RANK() не всегда возвращает последовательные целые числа.
Предположим, у нас есть пример таблицы следующим образом:
Следующий оператор использует функцию RANK() для присвоения ранга каждой строке из набора результатов в таблице t:
Как видите, второй и третий ряды имеют одинаковые связи, поэтому они получают одинаковое звание 2.
Четвертый ряд имеет ранг 4, потому что функция RANK() пропускает ранг 3.
Пример функции RANK() в MySQL
Давайте для демонстрации используем таблицу sales, созданную в руководстве по оконным функциям.
Если вы еще не создали таблицу sales, вот скрипт:
Следующий оператор использует функцию RANK() для ранжирования сотрудников по продажам по сумме продаж в каждом году:
- Во-первых, предложение PARTITION BY разбивает результирующие наборы на разделы по финансовым годам.
- Затем предложение ORDER BY сортирует сотрудников по продажам в порядке убывания.
Функция RANK() в MySQL с примером CTE
Следующий оператор использует функцию RANK() для поиска трех самых высоких заказов в каждом году:
- Сначала мы использовали общее табличное выражение (CTE), чтобы получить номер заказа, год заказа и ранг. Чтобы ранжировать заказы по значению заказа в каждом году, мы использовали функцию RANK(), которая разбивала строки по годам заказа и сортировала значение заказа по убыванию.
- Затем мы выбрали только ордера, чей ранг меньше или равен трем.
В этой статье вы узнали, как использовать функцию RANK() в MySQL для присвоения ранга каждой строке в наборе результатов.
Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.
Источник