ORDER BY et LIMIT : ordre et classements
What you'll learn
- trier le résultat avec
ORDER BYpar colonnes, expressions et , enASCou enDESC - produire des classements avec la combinaison
ORDER BY ... DESC LIMIT n - contrôler la position des
NULLdans le tri avecNULLS FIRST/NULLS LAST - rendre l'ordre déterministe en cas d'ex æquo en ajoutant une clé unique au tri
Mettre de l'ordre et prendre le haut du panier
Jusqu'ici, l'archive répondait en vrac : les lignes arrivaient dans l'ordre le plus pratique pour une machine, pas pour un humain. Aujourd'hui, pour la première fois, tu mets de l'ordre dans la sortie, et « Kotomarket » révèle autre chose que des lignes : ce que ce magasin jugeait cher, et ce qui se vendait bien.
ORDER BY colonne fixe l'ordre du résultat : croissant (ASC, par défaut) ou décroissant (DESC). On peut trier par plusieurs colonnes séparées par des virgules ; c'est ainsi qu'on obtient un rapport stable, pas un tas de lignes au hasard.
LIMIT n ne garde que les n premières lignes. La combinaison ORDER BY ... DESC LIMIT n est le classement classique : les articles les plus chers, les plus grosses commandes, les événements les plus récents. Sans tri, les « premières » lignes ne promettent rien.
QUERY : « Les premières lignes sans
ORDER BY», c'est comme « le meilleur objet exposé, choisi au hasard ». L'archive ne promet aucun ordre tant que tu ne le demandes pas.

ORDER BY dispose les lignes en escalier, LIMIT en prend le haut : le premier classement du magasin revenu à la vie.Без ORDER BY порядка нет
Очень важное правило:
SQL не гарантирует порядок строк без ORDER BY.
Например:
SELECT id, name, price
FROM products;
Такой запрос может сегодня вернуть строки в одном порядке, а завтра — в другом.
Иногда кажется, что база возвращает строки:
- в порядке вставки;
- по
id; - как они лежат в таблице;
- как они отображаются в интерфейсе.
Но на это нельзя опираться.
База может выбрать другой , использовать другой , иначе прочитать данные после обновления статистики или после изменения таблицы. И порядок результата поменяется, хотя сам SQL-запрос останется тем же.
Если порядок важен, он должен быть явно написан:
SELECT id, name, price
FROM products
ORDER BY id;
или:
SELECT id, name, price
FROM products
ORDER BY price DESC;
Правило простое:
Нет
ORDER BY— нет обещанного порядка.
Это особенно важно перед LIMIT. Потому что LIMIT берёт «первые строки», а без сортировки непонятно, какие строки база посчитает первыми.
ORDER BY aligne d'abord toutes les lignes du résultat ; ensuite seulement, LIMIT en découpe le haut.price.| name | price |
|---|---|
| Смарт-часы | 8990.00 |
| Беспроводные наушники | 5990.00 |
| Кроссовки беговые | 5490.00 |
| Механическая клавиатура | 4590.00 |
| Кофеварка капельная | 4290.00 |
ASC и DESC
У ORDER BY есть два направления сортировки.
ASC — по возрастанию:
SELECT name, price
FROM products
ORDER BY price ASC;
Для цены это значит:
сначала дешёвые, потом дорогие.
DESC — по убыванию:
SELECT name, price
FROM products
ORDER BY price DESC;
Для цены это значит:
сначала дорогие, потом дешёвые.
Если направление не указано, используется ASC.
То есть эти два запроса равнозначны:
SELECT name, price
FROM products
ORDER BY price;
SELECT name, price
FROM products
ORDER BY price ASC;
Для новичка полезно читать запрос вслух:
ORDER BY price ASC
— отсортируй по цене от меньшей к большей.
ORDER BY price DESC
— отсортируй по цене от большей к меньшей.
LIMIT: взять только первые строки
LIMIT ограничивает количество строк в результате.
Например:
SELECT name, price
FROM products
LIMIT 3;
Этот запрос вернёт только три строки.
Но сам по себе LIMIT не говорит, какие именно строки нужны. Он просто отрезает первые строки из того результата, который получился.
Поэтому для осмысленной выборки LIMIT почти всегда используют вместе с ORDER BY.
Три самых дешёвых товара:
SELECT name, price
FROM products
ORDER BY price ASC
LIMIT 3;
Три самых дорогих товара:
SELECT name, price
FROM products
ORDER BY price DESC
LIMIT 3;
Самые свежие заказы:
SELECT id, user_id, created_at
FROM orders
ORDER BY created_at DESC
LIMIT 10;
Логика всегда одинаковая:
ORDER BYвыстраивает строки в нужном порядке.LIMITберёт верхушку этого порядка.
ORDER BY price DESC
LIMIT 5
читается так:
поставь самые дорогие товары наверх и возьми первые пять.
Почему ORDER BY стоит почти в конце запроса
В SQL порядок записи частей запроса не полностью совпадает с тем, как удобно думать о его выполнении.
Например:
SELECT name, price
FROM products
WHERE category = 'Книги'
ORDER BY price DESC
LIMIT 5;
Такой запрос можно читать по шагам:
FROM products— возьми таблицу товаров.WHERE category = 'Книги'— оставь только книги.SELECT name, price— выбери нужные столбцы.ORDER BY price DESC— отсортируй результат по цене.LIMIT 5— оставь первые пять строк.
То есть сортировка применяется не ко всей таблице вообще, а к результату после фильтрации.
Если в таблице есть тысяча товаров, но книг только двадцать, то запрос сначала оставит книги, потом отсортирует эти книги по цене и затем возьмёт пять самых дорогих.
Это помогает правильно читать запросы:
WHERE
отвечает за то, какие строки участвуют.
ORDER BY
отвечает за то, в каком порядке они будут показаны.
LIMIT
отвечает за то, сколько строк останется сверху.
Сортировка по нескольким столбцам
Иногда одного столбца недостаточно.
Например, нужно отсортировать товары:
- сначала по категории;
- внутри каждой категории — по цене от дорогих к дешёвым.
Для этого в ORDER BY перечисляют несколько выражений через запятую:
SELECT name, category, price
FROM products
ORDER BY category ASC, price DESC;
Этот запрос читается так:
сначала отсортируй по категории по возрастанию, а если категория одинаковая — внутри неё отсортируй по цене по убыванию.
Пример результата:
| name | category | price |
|---|---|---|
| Домик-портал | Аксессуары | 3000 |
| Миска антигравитационная | Аксессуары | 1000 |
| Игрушка «Лазерная мышь» | Игрушки | 1700 |
| Игрушка «Мышь-перехватчик» | Игрушки | 900 |
| Книга «SQL для котонавтов» | Книги | 2500 |
| Книга «Память старой Земли» | Книги | 1200 |
Первый ключ сортировки главный:
category ASC
Он собирает строки по категориям.
Второй ключ применяется только там, где первый одинаковый:
price DESC
Он упорядочивает товары внутри одной категории.
Можно задавать своё направление для каждого столбца:
ORDER BY category ASC, price DESC, name ASC
Это значит:
- категория по возрастанию;
- внутри категории цена по убыванию;
- если цена одинаковая, название по возрастанию.
Сортировка по выражению
Сортировать можно не только по готовому столбцу, но и по вычислению.
Например, в таблице products есть:
price— цена товара;stock— остаток на складе.
Если нужно понять, какие товары занимают больше всего денег на складе, можно посчитать складскую стоимость:
price * stock
Запрос:
SELECT name, price, stock
FROM products
ORDER BY price * stock DESC;
Он сортирует товары не просто по цене и не просто по остатку, а по произведению цены на количество.
То есть товар за 1000 с остатком 100 может оказаться выше, чем товар за 5000 с остатком 2.
Потому что:
1000 * 100 = 100000
5000 * 2 = 10000
ORDER BY умеет работать с такими выражениями:
ORDER BY price * stock DESC
Это удобно, когда порядок зависит от расчёта, а не от одного столбца.
Сортировка по алиасу
Если выражение длинное, его неудобно повторять в ORDER BY.
Можно дать выражению имя через :
SELECT
name,
price,
stock,
price * stock AS stock_value
FROM products
ORDER BY stock_value DESC;
Здесь:
price * stock AS stock_value
создаёт в результате вычисляемый столбец stock_value.
А потом:
ORDER BY stock_value DESC
сортирует по этому вычисленному значению.
Это работает потому, что ORDER BY логически применяется после формирования списка SELECT. К моменту сортировки алиас stock_value уже существует.
Но важно не перепутать с WHERE.
Так нельзя:
SELECT
name,
price,
stock,
price * stock AS stock_value
FROM products
WHERE stock_value > 10000;
В WHERE алиас из SELECT ещё недоступен.
Правильно либо повторить выражение:
SELECT
name,
price,
stock,
price * stock AS stock_value
FROM products
WHERE price * stock > 10000
ORDER BY stock_value DESC;
Либо использовать — но это уже тема следующих модулей.
Главная мысль этого урока:
В
ORDER BYалиас изSELECTиспользовать можно. ВWHERE— нельзя.
stock_value.| name | price | stock | stock_value |
|---|---|---|---|
| Беспроводные наушники | 5990.00 | 120 | 718800.00 |
| Смарт-часы | 8990.00 | 60 | 539400.00 |
| Худи оверсайз | 2990.00 | 110 | 328900.00 |
| Механическая клавиатура | 4590.00 | 70 | 321300.00 |
| Портативная колонка | 3490.00 | 90 | 314100.00 |
Куда попадают NULL при сортировке
NULL означает отсутствие значения. При сортировке нужно решить, где такие строки окажутся:
- в начале;
- в конце.
В PostgreSQL по умолчанию NULL при сортировке считается больше любого обычного значения.
Поэтому при сортировке по возрастанию:
ORDER BY city ASC
строки с NULL окажутся в конце.
А при сортировке по убыванию:
ORDER BY city DESC
строки с NULL окажутся в начале.
Чтобы не зависеть от умолчаний, можно написать явно:
ORDER BY city ASC NULLS FIRST
Это значит:
сортируй города по возрастанию, но строки без города поставь в начало.
Или:
ORDER BY city ASC NULLS LAST
Это значит:
сортируй города по возрастанию, а строки без города поставь в конец.
Можно использовать и с DESC:
ORDER BY price DESC NULLS LAST
Это удобно для топов.
Например, если у некоторых товаров цена неизвестна, то запрос:
SELECT name, price
FROM products
ORDER BY price DESC
LIMIT 5;
в PostgreSQL может поднять товары с NULL наверх, потому что при DESC NULL идут первыми.
Чтобы получить именно самые дорогие товары с известной ценой, лучше написать:
SELECT name, price
FROM products
ORDER BY price DESC NULLS LAST
LIMIT 5;
Так товары с неизвестной ценой не помешают топу.
Важно для переносимости: в разных порядок NULL по умолчанию может отличаться. В PostgreSQL можно явно использовать NULLS FIRST и NULLS LAST. В MySQL такой синтаксис не используется, и поведение по умолчанию другое: NULL обычно считается меньше обычных значений.
| name | price |
|---|---|
| Смарт-часы | 8990.00 |
| Беспроводные наушники | 5990.00 |
| Кроссовки беговые | 5490.00 |
| Механическая клавиатура | 4590.00 |
| Кофеварка капельная | 4290.00 |
Ничьи: когда значения одинаковые
Представь, что мы выбираем три самых дорогих товара:
SELECT id, name, price
FROM products
ORDER BY price DESC
LIMIT 3;
Если цены у всех товаров разные, порядок понятен.
Но что если несколько товаров стоят одинаково?
Например:
| id | name | price |
|---|---|---|
| 10 | Домик-портал | 3000 |
| 11 | Когтеточка орбитальная | 3000 |
| 12 | Лежанка капитана | 3000 |
| 13 | Миска антигравитационная | 1000 |
У первых трёх товаров одинаковая цена.
Условие:
ORDER BY price DESC
гарантирует только одно:
товары за 3000 будут выше товаров за 1000.
Но оно не гарантирует, в каком порядке между собой будут товары за 3000.
Для глаза это может казаться мелочью. Но для отчётов, тестов и это важно.
Если несколько строк имеют одинаковое значение в столбце сортировки, их взаимный порядок не определён. Он может измениться после обновления данных, смены или даже между похожими запусками.
Чтобы порядок стал полностью предсказуемым, добавляют второй ключ сортировки — обычно уникальный id:
SELECT id, name, price
FROM products
ORDER BY price DESC, id ASC
LIMIT 3;
Теперь сортировка читается так:
- сначала по цене от дорогих к дешёвым;
- если цена одинаковая — по
idот меньшего к большему.
Такой порядок уже стабилен.
Стабильный порядок для LIMIT и страниц
Недетерминированный порядок особенно опасен вместе с LIMIT.
Например:
SELECT id, name, price
FROM products
ORDER BY price DESC
LIMIT 10;
Если у многих товаров одинаковая цена, база может выбрать любые десять строк из группы с равными значениями на границе топа.
Сегодня товар попадёт в топ-10.
Завтра при тех же ценах может не попасть.
Это не баг базы. Просто ты не полностью описал порядок.
Для стабильного результата добавляй уникальный столбец в конец сортировки:
SELECT id, name, price
FROM products
ORDER BY price DESC, id ASC
LIMIT 10;
Особенно это важно для .
Например, первая страница:
ORDER BY price DESC
LIMIT 10
и вторая страница через смещение:
ORDER BY price DESC
LIMIT 10 OFFSET 10
Если у строк одинаковая цена и нет дополнительной сортировки по id, одна и та же строка может «прыгать» между страницами.
Надёжнее:
ORDER BY price DESC, id ASC
LIMIT 10 OFFSET 10
Главное правило:
Если используешь
LIMITдля отчёта, топа или страницы, сортировка должна полностью определять порядок строк.
Можно ли сортировать по столбцу, которого нет в SELECT
Часто в отчёте не хочется показывать технические столбцы, но по ним нужно отсортировать результат.
Например, нужно показать названия товаров, но отсортировать их по цене:
SELECT name
FROM products
ORDER BY price DESC;
Так можно.
price не обязан быть в списке SELECT, чтобы использоваться в ORDER BY.
Запрос вернёт только name, но порядок строк будет определён ценой.
Это удобно, когда столбец нужен для логики выдачи, но не нужен читателю результата.
Например:
SELECT name
FROM products
ORDER BY created_at DESC
LIMIT 10;
Так можно получить названия десяти самых новых товаров, не показывая дату создания.
Типовые связки ORDER BY и LIMIT
Связка ORDER BY + LIMIT появляется в SQL постоянно.
Самые дорогие товары:
SELECT name, price
FROM products
ORDER BY price DESC
LIMIT 5;
Самые дешёвые товары:
SELECT name, price
FROM products
ORDER BY price ASC
LIMIT 5;
Самые свежие заказы:
SELECT id, user_id, created_at
FROM orders
ORDER BY created_at DESC
LIMIT 10;
Первые пользователи по алфавиту:
SELECT id, name
FROM users
ORDER BY name ASC
LIMIT 20;
Товары с самым большим остатком:
SELECT name, stock
FROM products
ORDER BY stock DESC
LIMIT 10;
Товары с максимальной складской стоимостью:
SELECT
name,
price,
stock,
price * stock AS stock_value
FROM products
ORDER BY stock_value DESC
LIMIT 10;
Во всех случаях схема одна:
ORDER BY что_считаем_важным
LIMIT сколько_строк_нужно
Главное правило для топов
LIMIT без ORDER BY не делает топ.
SELECT name, price
FROM products
LIMIT 5;
Это не пять самых дорогих товаров.
Это не пять самых дешёвых товаров.
Это просто пять строк, которые база вернула первыми.
Топ появляется только тогда, когда ты явно задаёшь критерий:
SELECT name, price
FROM products
ORDER BY price DESC
LIMIT 5;
Здесь критерий — цена по убыванию.
Interview question
Question d'entretien : SQL garantit-il l'ordre des lignes sans ORDER BY ? Et avec un ORDER BY sur une colonne où plusieurs valeurs sont identiques ?
Bonne réponse : sans ORDER BY, l'ordre n'est pas garanti du tout : il dépend du plan d'exécution et peut changer d'une exécution à l'autre. « Les lignes reviennent dans l'ordre d'insertion » est un mythe sur lequel on ne peut pas s'appuyer. Avec ORDER BY, seul l'ordre défini par les expressions indiquées est garanti : au sein des groupes de valeurs égales, l'ordre reste non déterministe. C'est pourquoi, pour des rapports stables et la , on complète toujours le tri par une clé unique : ORDER BY price DESC, id.
ORDER BY?ORDER BY created_at DESC LIMIT 10?id в ORDER BY price DESC, id?SELECT в ORDER BY?КВЕРИ: Сначала скажи архиву, что считать важным. Только потом проси верхушку.