ORDER BY
Сортировка результатов запроса
Теория
Когда вы пишете обычный SELECT запрос, СУБД может вернуть строки таблицы в любом удобном для неё порядке. Иногда кажется, что порядок «и так правильный», но это случайность, а не гарантия. Без специального дополнительного оператора сортировки строки в большинстве случаев будут выводиться в результате в случайном порядке. За порядок строк в результате выполнения SQL запроса отвечает оператор ORDER BY.
ORDER BY нужен, когда вы хотите получить предсказуемый результат. Например:
• показать работников с самой высокой зарплатой вверху;
• отсортировать товары по цене от меньшей к большей;
• вывести последние заказы по дате первыми;
• внутри каждого города отсортировать пользователей по дате регистрации.
Сортировка бывает двух типов:
• ASC — по возрастанию (это значение по умолчанию);
• DESC — по убыванию.
Сортировать можно и по нескольким столбцам. В этом случае получается многоуровневая сортировка: сначала по первому столбцу, а если значения первого столбца одинаковые — по второму внутри групп одинаковых значений первого.
ORDER BY нужен, когда вы хотите получить предсказуемый результат. Например:
• показать работников с самой высокой зарплатой вверху;
• отсортировать товары по цене от меньшей к большей;
• вывести последние заказы по дате первыми;
• внутри каждого города отсортировать пользователей по дате регистрации.
Сортировка бывает двух типов:
• ASC — по возрастанию (это значение по умолчанию);
• DESC — по убыванию.
Сортировать можно и по нескольким столбцам. В этом случае получается многоуровневая сортировка: сначала по первому столбцу, а если значения первого столбца одинаковые — по второму внутри групп одинаковых значений первого.
Синтаксис
SELECT column1, -- указываем столбцы, которые хотим получить
column2,
column3
FROM table_name -- указываем таблицу, из которой берём данные
ORDER BY column3 [ASC|DESC]; -- сортируем результат по столбцу column3
[ASC|DESC] -- выбираем порядок сортировки: ASC — по возрастанию, DESC — по убыванию
SQL
После ORDER BY вы указываете столбец, по которому хотите упорядочить результат. Если направление не указано, SQL применяет сортировку по возрастанию, то есть ASC.
Если нужно отсортировать в порядке убывания, пишите после столбца ключевое слово DESC. Например, для зарплаты это обычно означает: самые большие значения будут первыми.
Можно указать несколько столбцов через запятую. Тогда сортировка идёт по шагам:
• сначала по первому столбцу;
• при одинаковых значениях первого столбца — по второму;
• затем по третьему, если он есть.
В ORDER BY можно использовать:
• псевдоним, который вы сами задали в этом же SELECT через AS, например если результату математического выражения price * 2 вы присвоили псевдоним AS double_price, дальше его можно будет использовать в сортировке ORDER BY double_price DESC;
• порядковый номер столбца в SELECT, например ORDER BY 3 DESC отсортирует результат по столбцу, который находится на третьей позиции в SELECT.
Чтобы не было путаницы с реальными столбцами таблицы, задавайте псевдонимам понятные и уникальные имена. И помните: псевдонимы удобны для сортировки, но в других частях запроса они доступны не всегда.
В PostgreSQL важно помнить и про NULL. NULL - это неопределенное значение (тема с NULL будет разобрана подробно в следующих темах). Их поведение в сортировке можно явно контролировать через NULLS FIRST или NULLS LAST, чтобы порядок не удивлял.
Важно: По умолчанию в сортировке в PostgreSQL значения NULL считаются как наибольшие значения над всеми остальными определенными значениями. Поэтому, если вы сортируете таблицу по столбцу в порядке возрастания, и этот столбец содержит значения NULL, они окажутся в конце выборки. Учтите это.
Если нужно отсортировать в порядке убывания, пишите после столбца ключевое слово DESC. Например, для зарплаты это обычно означает: самые большие значения будут первыми.
Можно указать несколько столбцов через запятую. Тогда сортировка идёт по шагам:
• сначала по первому столбцу;
• при одинаковых значениях первого столбца — по второму;
• затем по третьему, если он есть.
В ORDER BY можно использовать:
• псевдоним, который вы сами задали в этом же SELECT через AS, например если результату математического выражения price * 2 вы присвоили псевдоним AS double_price, дальше его можно будет использовать в сортировке ORDER BY double_price DESC;
• порядковый номер столбца в SELECT, например ORDER BY 3 DESC отсортирует результат по столбцу, который находится на третьей позиции в SELECT.
Чтобы не было путаницы с реальными столбцами таблицы, задавайте псевдонимам понятные и уникальные имена. И помните: псевдонимы удобны для сортировки, но в других частях запроса они доступны не всегда.
В PostgreSQL важно помнить и про NULL. NULL - это неопределенное значение (тема с NULL будет разобрана подробно в следующих темах). Их поведение в сортировке можно явно контролировать через NULLS FIRST или NULLS LAST, чтобы порядок не удивлял.
Важно: По умолчанию в сортировке в PostgreSQL значения NULL считаются как наибольшие значения над всеми остальными определенными значениями. Поэтому, если вы сортируете таблицу по столбцу в порядке возрастания, и этот столбец содержит значения NULL, они окажутся в конце выборки. Учтите это.
Примеры
1. Работники по зарплате: от большей к меньшей
Классический случай: выведем самых высокооплачиваемых сотрудников компании. Для этого используем сортировку с указанием DESC.
🔄 Попробуйте изменить запрос:
- • Поменяйте DESC на ASC и сравните порядок
- • Добавьте в выборку position
2. Товары: сначала категория, внутри категории — цена
Это многоуровневая сортировка. Сначала товары сортируются по category, а внутри каждой категории в случае их совпадений идут от более дорогих к более дешевым.
🔄 Попробуйте изменить запрос:
- • Поменяйте второй столбец в сортировке на price ASC
- • Добавьте третий столбец: product_name ASC
3. Заказы по дате: новые выше, старые ниже
В отчетах такой запрос встречается постоянно: последние события должны быть наверху. Здесь это даёт ORDER BY order_date DESC.
🔄 Попробуйте изменить запрос:
- • Добавьте второй столбец в сортировку: user_id ASC
- • Попробуйте вместо столбца order_date в сортировке написать номер позиции этого столбца, то есть число 3
4. Пользователи по городу и дате регистрации
Запрос показывает сортировку по столбцам с текстом и датой: по городам по алфавиту, а внутри города — идут сначала новые пользователи.
🔄 Попробуйте изменить запрос:
- • Поменяйте порядок столбцов: сначала registration_date, потом city
5. Сортировка по вычисляемому выражению
В этом примере сортировка выполняется не по исходному столбцу, а по вычисленному значению. Выражение price * 2 получает псевдоним double_price через AS, и сортировка выполняется по псевдониму.
🔄 Попробуйте изменить запрос:
- • Поменяйте сортировку на само выражение price * 2 вместо псевдонимы
- • Замените ORDER BY double_price DESC на ORDER BY 3 DESC и сравните результат
6. Демонстрация NULLS FIRST и NULLS LAST
Этот пример из таблицы users, где у части пользователей город не указан, то есть вместо городов у пользователей значение NULL. При NULLS LAST строки с NULL в city окажутся в конце результата.
🔄 Попробуйте изменить запрос:
- • Замените на NULLS FIRST и сравните результат
- • Уберите NULLS FIRST или NULLS LAST и проверьте поведение по умолчанию и поведение с DESC
Типичные ошибки
Надеются на «естественный» порядок без ORDER BY
Без явной сортировки СУБД не обязана возвращать строки в стабильной последовательности. Сегодня порядок один, после изменений в данных может стать другим.
Путают направление сортировки
ASC — по возрастанию, DESC — по убыванию. Если направление не указано, используется по умолчанию ASC.
Неверно понимают многоуровневую сортировку
В запросе ORDER BY city, registration_date DESC второй столбец сортировки применяется только внутри одинаковых city. Это не «две независимые сортировки».
Забывают про одинаковые значения и «скачущий» порядок
Если у нескольких строк есть одинаковые значения столбца сортировки, их взаимный порядок не гарантирован. Для стабильности добавляйте второй столбец сортировки, например ORDER BY salary DESC, worker_id ASC.
Не управляют положением NULL
Чтобы получить нужный результат, явно задавайте NULLS FIRST или NULLS LAST, особенно в отчетах.
Практика
Проверь себя
Ответьте на вопросы, чтобы закрепить материал:
1
Есть запрос: SELECT first_name, salary FROM workers ORDER BY salary; Какой порядок зарплат он задаст по умолчанию?
2
Что означает этот фрагмент запроса: ORDER BY city, registration_date DESC?
3
В PostgreSQL где окажутся строки с NULL в запросе ORDER BY salary DESC, если не писать NULLS FIRST/LAST?
4
Напишите запрос, который выведет worker_id, first_name, department_id из таблицы workers и отсортирует сотрудников сначала по отделу, а внутри отдела — по имени.
5
Напишите запрос, который выведет product_name, category, price из products и отсортирует данные по категории в обратном алфавитном порядке, а внутри категории — по цене по возрастанию.
6
Что будет главным столбцом сортировки в запросе ORDER BY department_id ASC, salary DESC?
7
Напишите запрос, который выведет order_id, status, order_date из orders и отсортирует данные сначала по статусу по алфавиту, а внутри статуса — по дате от более ранних к более поздним.
8
Как правильно изменить ORDER BY salary DESC, чтобы NULL были в конце?