Сортировка результатов SQL запроса с помощью оператора ORDER BY

Сортировка результатов SQL запроса с помощью оператора ORDER BY
Евгений Буторин

Введение

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

Например, вы оцениваете несколько продуктов и, вашему стейкхолдеру (заказчику) важно понимать какой продукт приносит наибольшую прибыль. На небольшом количестве данных это можно оценить визуально, но если таких продуктов более 100, то это становится настоящей проблемой. Конечно, это можно сделать в экселе, скопировав туда значения и, выполнив сортировку в нужном порядке. Но как быть когда вас просят вывести только 30 наиболее прибыльных продуктов из 100?

Для этого необходимо использовать сортировку данных прямо внутри SQL-запроса. Чтобы отсортировать данные необходимо использовать оператор ORDER BY.

Оператор ORDER BY

ORDER BY, в переводе с английского, означает «сортировать по». Сортировать данные можно по любому полю, по любому типу данных и в любом направлении. Для этого используются ключевые слова:

  • ASC (от английского ascending - по возрастанию);
  • DESC (от английского descending - по убыванию).

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

SELECT columns FROM table ORDER BY column [ASC | DESC];

В большинстве СУБД вы можете не указывать ASC, так как оно используется по умолчанию. В этом случае, запрос будет выглядеть как:

SELECT columns FROM table ORDER BY column;

Сортировка по возрастанию и убыванию

Сортировка данных позволяет расположить строки таблицы в указанном порядке по выбранному столбцу:

+-------------------+-----------------------------------------------------+-----------------------------------------------+ |Тип данных | Описание сортировки по возрастанию (ASC)| Описание сортировки по убыванию (DESC)| +-------------------+-----------------------------------------------------+-----------------------------------------------+ |Строковый тип данных | При сортировке строкового типа данных, SQL выведет вам результат, отсортированный от А до Я или от A до Z. Если в данных есть два наименования, начинающиеся на одинаковую букву, то SQL после учета первой буквы, будет смотреть по следующей и так далее. Например, при сортировке имен “Анна”, “Алексей” и “Алена”, сначала будет идти “Алексей”, потом “Алена”, а потом уже “Анна”.| При сортировке строкового типа данных, SQL выведет вам результат, отсортированный от Я до А или от Z до A. Если в данных есть два наименования, начинающиеся на одинаковую букву, то SQL после учета первой буквы, будет смотреть по следующей и так далее. Например, при сортировке имен “Ярослав”, “Алексей”, “Анна” и “Дмитрий”, сначала будет идти “Ярослав”, следом “Дмитрий”, потом “Анна”, а потом уже “Алексей”. | +-------------------+-----------------------------------------------------+-----------------------------------------------+ |Числовой тип данных | Сортировка по столбцу с числовым типом данных выведет строки, отсортированные от меньшего к большему. Например, 1, 2, 3, 4, 5 и так далее. Если в данных попадается два одинаковых значения, например, 1 и 1, то строки сортируются сначала по числу, а затем в случайном порядке (если не указана сортировка по второму столбцу). | Сортировка по столбцу с числовым типом данных выведет строки, отсортированные от большего к меньшему. Например, 5, 4, 3, 2, 1. Если в данных попадается два одинаковых значения, например, 5 и 5, то строки сортируются сначала по числу, а затем в случайном порядке (если не указана сортировка по второму столбцу).| +-------------------+-----------------------------------------------------+-----------------------------------------------+ | Дата и время | Даты и время, ведут себя как числовой тип данных и, если явно указан формат даты, то сортировка будет соответствовать дате (включая день, месяц и год). Например, даты “01.12.2023”, “04.03.2024”, “03.03.2024” будут отсортированы по возрастанию следующим образом: “01.12.2023”, “03.03.2024”, “04.03.2024”. | Даты и время, ведут себя как числовой тип данных и, если явно указан формат даты, то сортировка будет соответствовать дате (включая день, месяц и год). Например, даты “01.12.2023”, “04.03.2024”, “03.03.2024” будут отсортированы по убыванию следующим образом: “04.03.2024”, “03.03.2024”, “01.12.2023”. +-------------------+-----------------------------------------------------+-----------------------------------------------+ |Булевые значения | При сортировке булевых значений (истина/ложь или true/false) по возрастанию, сначала будет идти false, а только потом true. Это связано с тем, что значения истинности (true и false), обычно обозначаются как 1 и 0, соответственно 0 < 1, поэтому и false < true.| При сортировке булевых значений (истина/ложь или true/false) по убыванию, сначала будет идти true, а только потом false. Это связано с тем, что значения истинности (true и false), обычно обозначаются как 1 и 0, соответственно 0 < 1, поэтому и false < true.|

Сортировка по нескольким полям

На примерах выше, мы видели, что при сортировке одинаковых значений мы получаем случайное положение строк внутри одной группы. Чтобы это исправить, применяется сортировка по нескольким столбцам. Она может быть как однонаправленная:

SELECT columns FROM table ORDER BY column1, column2 [ASC | DESC];

Так и разнонаправленная:

SELECT columns FROM table ORDER BY column1 ASC, column 2 DESC.

Полей может быть и больше. Все зависит от ваших потребностей. Однако, стоит понимать, что сортировка утяжеляет запрос, поэтому не рекомендуется применять ее без необходимости.

Использование ORDER BY в оконных функциях

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

Пример такой оконной функции служит ROW_NUMBER(), которую часто используют для поиска более сложного упорядочивания строк внутри партиции или без нее. Она имеет следующий вид:

ROW_NUMBER() OVER(ORDER BY columns) или ROW_NUMBER() OVER(PARTITION BY columns ORDER BY columns)

Оптимизация использования ORDER BY

Любой запрос который вы делаете в SQL имеет свою последовательность исполнения команд. Выглядит он следующим образом:

  1. FROM
  2. JOIN
  3. WHERE
  4. GROUP BY
  5. HAVING
  6. SELECT
  7. DISTINCT
  8. ORDER BY
  9. LIMIT

Как мы видим, ORDER BY находится в самом конце списка, что позволяет нам оптимизировать его использование.

Давайте рассмотрим три примера:

SELECT product, regionName as name, priceWithDisc FROM sales ORDER BY product, regionName
SELECT product, regionName as name, priceWithDisc FROM sales ORDER BY product, name
SELECT product, regionName as name, priceWithDisc FROM sales ORDER BY 1, 2

Если исполнить все три запроса, то мы получим одинаковый вид сортировки и одинаковый итоговый вид выведенных данных. Эта особенность ORDER BY позволяет нам не использовать оригинальные названия столбцов, вместо этого указывая элиас (псевдоним, который мы присвоили столбцу) или порядковый номер столбца.

Примеры

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

Для вывода данных я воспользовался запросом:

SELECT * FROM production;

Сортировка по алфавиту

Сортировка по алфавиту позволит нам сделать выведенную информацию более удобной для восприятия. Для этого достаточно добавить ORDER BY в конце запроса и указать столбец PRODUCT:

SELECT * FROM production ORDER BY product;

Сортировка по дате

Теперь давайте отсортируем по дате – в нашем случае по месяцу.

SELECT * FROM production ORDER BY month;

На выходе мы получим следующий результат:

Сортировка по нескольким полям

Данный результат не удобен для чтения поэтому я предлагаю сделать сортировку по двум полям - по продукту и по месяцу.

SELECT * FROM production ORDER BY 1, 2;

В итоге мы получим следующий результат:

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

Отличие ORDER BY и GROUP BY

Аналитики, которые только начинают свой путь и знакомятся с SQL могут путать ORDER BY (“сортировать по”) и GROUP BY (“группировать по”). Однако эти две команды абсолютно разные. GROUP BY используется только при применении в запросе агрегирующих функций, таких как SUM, MAX, MIN, COUNT и AVG. При этом, использование одного оператора не исключает использование другого. Для примера давайте напишем команду, которая покажет сумму платежей по менеджерам и отсортируем ее по убыванию платежей:

SELECT manager_name, SUM(payments) as pay FROM payments GROUP BY manager_name ORDER BY pay DESC;

После выполнения кода мы получим следующий результат:

Заключение

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

Спасибо за заявку

В ближайшее время мы с Вами свяжемся