Rank sql: RANK() and DENSE_RANK() functions | Interactive tutorial on SQL

5 Advanced SQL концептов которые нужно знать в 2022 — bool.dev

1. Common Table Expressions (CTEs)

При работе с данными иногда вам нужно запросить результаты другого запроса. Простой способ добиться этого — использовать sub-query.

Однако с ростом сложности sub-query вычислений становятся трудными для чтения и отладки.  Именно тогда на сцену выходят CTE, которые облегчают вашу жизнь. CTE упрощают написание и обслуживание сложных запросов. ✅ 

Например, рассмотрим следующее извлечение данных с использованием  sub-query:

SELECT Sales_Manager, Product_Category, UnitPrice
FROM Dummy_Sales_Data_v1
WHERE Sales_Manager IN (SELECT DISTINCT Sales_Manager
                        FROM Dummy_Sales_Data_v1
                        WHERE Shipping_Address = 'Germany'
                        AND UnitPrice > 150)
AND Product_Category IN (SELECT DISTINCT Product_Category
                         FROM Dummy_Sales_Data_v1
                         WHERE Product_Category = 'Healthcare'
                         AND UnitPrice > 150)
ORDER BY UnitPrice DESC

Здесь используется только два подзапроса с понятным кодом.

Если добавить больше вычислений в подзапросы или даже добавить еще несколько подзапросов — сложность возрастает , что делает код менее читабельным и трудным в обслуживании.

Теперь давайте посмотрим на упрощенную версию вышеуказанного подзапроса с CTE:

WITH SM AS
(
SELECT DISTINCT Sales_Manager
FROM Dummy_Sales_Data_v1
WHERE Shipping_Address = 'Germany'
AND UnitPrice > 150
),
PC AS
(
SELECT DISTINCT Product_Category
FROM Dummy_Sales_Data_v1
WHERE Product_Category = 'Healthcare'
AND UnitPrice > 150
)
SELECT Sales_Manager, Product_Category, UnitPrice
FROM Dummy_Sales_Data_v1
WHERE Product_Category IN (SELECT Product_Category FROM PC)
AND Sales_Manager IN (SELECT Sales_Manager FROM SM)
ORDER BY UnitPrice DESC

Сложный подзапрос разбивается на более простые блоки кодов, которые необходимо использовать.

Таким образом, сложные подзапросы переписываются в два CTE SM, PCкоторые легче читать и изменять. 🎯

Оба приведенных выше запроса, требующие одинакового времени для выполнения, вернули такой результат:

CTE по существу позволяют вам создать временную таблицу из результата запроса. Это улучшает читаемость кода и его обслуживание. ✅

Реальные наборы данных могут содержать миллионы или миллиарды строк, занимающих тысячи ГБ памяти. Выполнение расчетов с использованием данных из этих таблиц и особенно непосредственное объединение их с другими таблицами будет довольно затратным.

Окончательным решением таких задач является использование CTE. 💯

Забегая вперед, давайте посмотрим, как можно присвоить целочисленный «ранг» каждой строке в наборе данных с помощью оконных функций.

2. ROW_NUMBER() vs RANK() vs DENSE_RANK()

Второй часто используемой концепцией при работе с реальными наборами данных является ранжирование записей. Компании используют его в различных сценариях, таких как:

  1. Рейтинг самых продаваемых брендов по количеству проданных единиц
  2. Ранжирование лучших продуктовых вертикалей по количеству заказов или полученному доходу
  3. Получение названия фильма в каждом жанре с наибольшим количеством просмотров

ROW_NUMBER, RANK()и DENSE_RANK()по существу используются для присвоения последовательных целых чисел каждой записи в указанном разделе результирующего набора.

Поведение и способ, которым целые числа присваиваются каждой записи, изменяются, когда в результирующей таблице есть повторяющиеся строки. ✅

Давайте рассмотрим пример с Dummy Sales Dataset, чтобы перечислить все категории продуктов, адрес доставки в порядке убывания стоимости доставки.

SELECT Product_Category,
  Shipping_Address,
  Shipping_Cost,
  ROW_NUMBER() OVER
              (PARTITION BY Product_Category,
                            Shipping_Address
               ORDER BY Shipping_Cost DESC) as RowNumber,
  RANK() OVER 
        (PARTITION BY Product_Category,
                      Shipping_Address
         ORDER BY Shipping_Cost DESC) as RankValues,
  DENSE_RANK() OVER 
              (PARTITION BY Product_Category,
                            Shipping_Address 
               ORDER BY Shipping_Cost DESC) as DenseRankValues
FROM Dummy_Sales_Data_v1
WHERE Product_Category IS NOT NULL
AND Shipping_Address IN ('Germany','India')
AND Status IN ('Delivered')

Как вы можете видеть, синтаксис для всех трех одинаковый, однако он приводит к разным выводам, как показано ниже:

RANK()is извлекает ранжированные строки на основе условия ORDER BYпредложения. Как видите, между первыми двумя строками есть связь, т. е. первые две строки имеют одинаковое значение в столбце Shipping_Cost ( о котором говорится в ORDER BYпункте ).

RANKприсваивает одно и то же целое число обеим строкам. Однако он добавляет количество повторяющихся строк к повторяющемуся рангу, чтобы получить ранг следующей строки. Вот почему третья строка ( отмечена красным ) RANKприсваивает ранг 3( 2 повторяющихся строки + 1 повторяющийся ранг )

DENSE_RANKпохож на RANK, но он не пропускает ни одного числа, даже если между строками есть ничья. Это вы можете увидеть в синей рамке на картинке выше.

В отличие от двух предыдущих, ROW_NUMBERпросто присваивает последовательные номера каждой записи в разделе, начиная с 1. Если он обнаруживает два одинаковых значения в одном разделе, он присваивает обоим разные ранговые номера.

Для следующего partition для product category > shipping address > Entertainment — India, rank по 3-м функциям начнется с 1-цы как показано ниже:

ROW_NUMBER, RANK, DENSE_RANK в разных Partition’ах

В конечном случае, если в столбце, который юзается для ORDER BY эти фунуции вернут один и тот же результат. 

3. CASE WHEN

Оператор Case позволит вам реализовать if-else в SQL.

При работе над реальными проектами данных оператор CASE часто используется для категоризации данных на основе значений в других столбцах. Его также можно использовать вместе с агрегатными функциями.

SELECT OrderID,
       OrderDate,
       Sales_Manager,
       Quantity,
       CASE WHEN Quantity > 51 THEN 'High'
            WHEN Quantity < 51 THEN 'Low'
            ELSE 'Medium' 
       END AS OrderVolume
FROM Dummy_Sales_Data_v1

В случае с конкретным примером выражение добавило доп колонку, где вставляет значение high, medium или low в зависимости от значений в столбце Quantity.

Другим часто используемым, но менее известным вариантом использования оператора CASE — Data Pivoting.

Data Pivoting — это когда мы меняем местами колонки со строками.

Например, давайте выясним, сколько заказов обработал каждый менеджер по продажам для Сингапура, Великобритании, Кении и Индии.

SELECT Sales_Manager,
       COUNT(CASE WHEN Shipping_Address = 'Singapore' THEN OrderID
             END) AS Singapore_Orders,
  
       COUNT(CASE WHEN Shipping_Address = 'UK' THEN OrderID
             END) AS UK_Orders,
     
       COUNT(CASE WHEN Shipping_Address = 'Kenya' THEN OrderID
             END) AS Kenya_Orders,
  
       COUNT(CASE WHEN Shipping_Address = 'India' THEN OrderID
             END) AS India_Orders
FROM Dummy_Sales_Data_v1
GROUP BY Sales_Manager

используя CASE..WHEN..THEN, мы создали отдельные столбцы для каждого адреса доставки, чтобы получить ожидаемый результат, как показано ниже.

В зависимости от ваших задач вы также можете использовать различные агрегации, такие как SUM, AVG, MAX, MIN с оператором CASE.

4. Extract Data From Date — Time Columns

В некоторых собесах или просто в рабочих задачах вас попросят агрегировать данные по месяцам или рассчитать определенные показатели за конкретный месяц.

И когда в наборе данных нет отдельного столбца месяца, вам нужно извлечь нужную часть даты из переменной даты и времени в данных.

Различные среды SQL имеют разные функции для извлечения частей даты. В MySQL вы должны знать —

EXTRACT(part_of_date FROM date_time_column_name)
YEAR(date_time_column_name)
MONTH(date_time_column_name)
MONTHNAME(date_time_column_name)
DATE_FORMAT(date_time_column_name)

например, давайте узнаем общее количество заказов каждый месяц 

SELECT strftime('%m', OrderDate) as Month,
       SUM(Quantity) as Total_Quantity
from Dummy_Sales_Data_v1
GROUP BY strftime('%m', OrderDate)

Ниже приведено изображение, на котором показаны наиболее часто извлекаемые части даты и ключевые слова, которые следует использовать в EXTRACTфункции.

5. SELF JOIN

Они точно такие же, как и другие JOIN в SQL, с той лишь разницей, что SELF JOINвы соединяете таблицу с самой собой.

Ключевого слова SELF JOINнет, вы просто юзаете join где обе таблицы, которые участвуют в нем — это одна и та же таблица

Напишите SQL-запрос, где вы находите сотрудников, которые зарабатывают больше, чем их менеджеры
. Один из наиболее часто задаваемых вопросов на собеседованиях.SELF JOIN

давайте возьмем это в качестве примера и создадим набор данных Dummy_Employees, как показано ниже.

И попробуйте узнать, какие сотрудники обрабатывают больше заказов, чем их менеджер, используя этот запрос:

SELECT t1.EmployeeName, t1.TotalOrders
FROM Dummy_Employees AS t1
JOIN Dummy_Employees AS t2
ON t1.ManagerID = t2.EmployeeID
WHERE t1.TotalOrders > t2.TotalOrders

Как и ожидалось, вернулись сотрудники — Абдул и Мария, — которые обработали больше заказов, чем их менеджер — Пабло.

Источник

Введение в функцию ранжирования в SQL

В SQL обычно выполняются различные агрегированные функции, такие как MIN, MAX и AVG. После выполнения этих функций вы получите вывод в виде одной строки. Чтобы определить ранги для каждого поля отдельно, SQL-сервер предоставляет функцию RANK(). Функция RANK() присваивает ранг, то есть целое число, каждой строке в группе наборов данных. Функция RANK() также известна как оконная функция. Прежде чем использовать функцию MYSQL RANK(), важно определить три вопроса:

  • Ранг какой?
  • В какой группе?
  • По какому рангу?

Теперь давайте проверим основной синтаксис функции RANK() в SQL.

Синтаксис

ВЫБЕРИТЕ имя_столбца,

RANK() OVER (PARTITION BY… ORDER BY…) как ранг

ОТ имя_таблицы;

В этом синтаксисе:

  • Имя_столбца представляет столбец, который вы хотите ранжировать в таблице
  • Предложение PARTITION BY делит строки набора результатов на разделы на основе одного или нескольких параметров
  • Предложение ORDER BY сортирует строки в каждом разделе, где применяется функция

Пример

Давайте рассмотрим приведенную ниже таблицу, чтобы ранжировать данное ИМЯ СТУДЕНТА на основе ОЦЕНОК СТУДЕНТОВ.

Приведенный ниже код ранжирует StudentName на основе StudentMarks, поскольку рейтинг будет храниться в новом столбце StudentRank.

Выход

Как видите, ученики ранжированы в соответствии с их оценками в приведенной выше таблице.

Использование функции SQL RANK() для набора результатов 

В этом примере вы узнаете, как использовать функцию RANK() для набора результатов. Данный запрос используется для ранжирования всех студентов на основе их оценок.

Теперь давайте посмотрим на результат вышеуказанного запроса.

Выход

Как видно из приведенного выше примера, предложение PARTITION BY отсутствует, поэтому запрос обрабатывает весь результирующий набор как один раздел.

Предложение ORDER BY используется для сортировки строк на основе оценок учащихся. Затем функция RANK() применяла результаты в строках в порядке убывания оценок учащихся.

Использование функции SQL RANK() над разделом

Теперь, чтобы понять функцию RANK() над разделом, добавьте еще 3 строки в таблицу, которую вы создали ранее, чтобы лучше понять предложение PARTITION BY.

Теперь это таблица, к которой вы будете применять функцию RANK(). В приведенную выше таблицу вы добавили еще 3 учащихся: Питера, Боба и Ким.

Выход

Примечание: приведенная выше таблица разделена по названию класса, и каждый учащийся в каждом классе оценивается по-разному. Это означает, что предложение ORDER BY применяется к каждому разделу отдельно, как упоминалось ранее.

Учащиеся каждого класса распределяются отдельно и ранжируются соответственно. В каждом 10-м, 4-м и 7-м классах есть только один ученик, поэтому учащиеся этих классов имеют ранг 1. 

В классе 3 учатся три разных ученика, поэтому они ранжируются в порядке убывания оценок учащихся, как указано в пункте ORDER BY. Точно так же были ранжированы учащиеся 9-го класса. Поскольку у них обоих одинаковые оценки, они оба получают ранг 1.

Получите опыт работы с новейшими инструментами и методами бизнес-аналитики с помощью Программы сертификации бизнес-аналитиков. Зарегистрируйтесь сейчас!

Заключение

На этом мы подошли к концу функции Rank() в SQL. Теперь, когда вы узнали о функции Rank(), пришло время изучить и изучить другие функции и предложения, предоставляемые SQL-сервером, и стать экспертом в этой области. Если вы хотите пройти сертификацию и освоить SQL от А до Я, вы должны пройти сертификационный курс Simplilearn по SQL.

Если у вас есть какие-либо сомнения относительно этого урока, не стесняйтесь оставлять их в разделе комментариев, и наши специалисты ответят на них за вас.

SQL — Расчет ранга | 1Ключевые данные

SQL > Расширенный SQL >
Ранг

В SQL есть несколько вариантов использования, в которых существует несколько способов решения проблемы. Отображение ранга значений — один из таких случаев. Здесь мы покажем два способа вычисления ранга. Первый без использования оконной функции, второй с использованием оконной функции.

Функция окна не используется

Общая идея отображения ранга в SQL состоит в том, чтобы выполнить самосоединение , затем перечислить результаты по порядку и, наконец, подсчитать количество записей, которые перечислены перед (и включая) интересующей записью. Давайте использовать пример для иллюстрации. Скажем, у нас есть следующая таблица,

Таблица Total_Sales

 Джон  10
 Jennifer   15 
 Stella   20 
 Sophia   40 
 Greg   50 
 Jeff   20 

we would type,

ВЫБЕРИТЕ a1.Name, a1.Sales, COUNT (a2.Sales) Sales_Rank

ОТ Total_Sales a1, Total_Sales a2

ГДЕ a1.Sales < a2.Sales ИЛИ (a1.Sales=a2.Sales AND a1.Name = a2.Name)
ГРУППИРОВАТЬ ПО a1.Name, a1.Sales

ЗАКАЗ ПО a1.Sales DESC, a1.Name DESC;

Результат:

9

Name   Sales   Sales_Rank
Greg  50  1
Sophia  40  2
Stella  20  3
Джефф 20 3
Дженнифер 15 5
JOHN 10 6

Обратите внимание, что в этом случае предложение WHERE учитывает возможность того, что несколько строк данных имеют одинаковое значение в столбце Продажи . Если мы точно знаем, что в столбце Sales нет повторяющихся значений, мы можем изменить предложение WHERE на:

ГДЕ a1.Продажи <= a2.Продажи

Использование оконной функции

Второй способ вычисления ранга — использование оконной функции. В этом случае мы будем использовать следующее:

ВЫБЕРИТЕ a1.Имя, Продажи, RANK() над (ЗАКАЗАТЬ ПО ПРОДАЖАМ DESC) RK

ОТ Total_Sales

ЗАКАЗ ПО a1.Sales DESC;

Результат:

9012

При использовании RANK() две связанные строки будут иметь один и тот же ранг. Эта функция будет учитывать количество связанных рядов и присваивать ранг последующим рядам. В этом примере две строки связаны для 3-го места, поэтому следующая строка, Дженнифер, получает ранг 5.

Вы также можете использовать функцию ROW_NUMBER() в оконной функции. В этом случае SQL будет следующим:

ВЫБЕРИТЕ a1.Name, Sales, ROW_NUMBER() над (ORDER BY Sales DESC) RK

ОТ Total_Sales

ЗАКАЗ ПО a1.Sales DESC;

Результат:

Имя   Продажи   RK
Greg   50  1
Sophia   40  2
Stella   20  3
Jeff   20  3
Дженнифер 15 5
Джон 10 6
Name   Sales   RK
Greg  50 1
Sophia  40 2
Stella  20 3
Джефф 20 4
Дженнифер 15 5
Джон 10 6

Обратите внимание, что в этом примере с одинаковой вероятностью Стелла или Джефф появятся первыми и получат ранг 3, потому что единственным критерием ORDER BY являются продажи, что приводит к равенству между этими двумя строками. Если у вас есть определенные критерии для разрешения ничьей, не забудьте включить их в ORDER BY . Например, если вы хотите, чтобы результаты отображались в алфавитном порядке по имени в случае ничьей, вы должны ввести,

ВЫБЕРИТЕ a1.Name, Sales, ROW_NUMBER() over (ORDER BY Sales DESC, Name) RK

ОТ Total_Sales

ЗАКАЗ ПО a1.Sales DESC;

Результат:

Name   Sales   Sales_Rank
Greg  50 1
Sophia  40 2
Jeff  20 3
Stella  20 4
Jennifer  15 5
John 10 6

Список сложных операций SQL

  Операция  Описание
 Рейтинг  Вычисляет рейтинг ряда чисел.

Imacros | Все права защищены © 2021