Основы выборки: SELECT, фильтрация и сортировка

ORDER BY и LIMIT / OFFSET

Содержание курса

WHERE научил нас отбирать нужные строки. Теперь встаёт следующий вопрос: в каком порядке эти строки появятся и как показать только часть из них? Именно это делают ORDER BY, LIMIT и OFFSET.

ORDER BY: направление сортировки ASC и DESC, сортировка по нескольким столбцам

Без ORDER BY СУБД возвращает строки в том порядке, в котором ей удобно их извлечь, — и этот порядок может меняться от запроса к запросу. ORDER BY фиксирует порядок явно.

Проще всего это видно на одном столбце:

SELECT title, price FROM products ORDER BY price;

Здесь строки выстроятся от наименьшей цены к наибольшей. Это поведение по умолчанию — восходящий порядок, ASC. Написать ORDER BY price ASC означает ровно то же самое; ключевое слово ASC просто делает намерение явным, что бывает полезно для читаемости кода в команде.

Чтобы развернуть порядок, добавляют DESC:

SELECT title, price FROM products ORDER BY price DESC;

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

По-настоящему интересный случай — несколько столбцов. Представьте таблицу orders со столбцами customer_id и amount. Нужно увидеть заказы, сгруппированные по покупателю, а внутри каждого покупателя — от самого дорогого к самому дешёвому:

SELECT customer_id, amount
FROM orders
ORDER BY customer_id ASC, amount DESC;

СУБД сначала сортирует по customer_id — все заказы одного покупателя собираются вместе. Когда значения customer_id совпадают, вступает второй критерий: amount DESC. Направление задаётся каждому столбцу отдельно; если написать просто ORDER BY customer_id, amount, оба столбца будут ASC.

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

Пример сортировки и OFFSET без готовой базы

Этот запрос можно выполнить целиком в SQLite или PostgreSQL. Блок WITH задаёт три товара прямо внутри запроса, поэтому создавать таблицу не нужно:

WITH products(product_id, title, price) AS (
    VALUES (1, 'Клавиатура', 3000),
           (2, 'Мышь', 1500),
           (3, 'Коврик', 1500)
)
SELECT product_id, title, price
FROM products
ORDER BY price DESC, product_id ASC
LIMIT 1 OFFSET 1;

Результат — 2 | Мышь | 1500. Сначала идёт клавиатура за 3000, затем мышь и коврик. OFFSET 1 пропускает клавиатуру, LIMIT 1 оставляет одну строку. Второй ключ сортировки product_id определяет порядок товаров с одинаковой ценой. Замените OFFSET на 2 — получите коврик.

Начать заново?

Помощник начнёт новый диалог по этой задаче. Текущая переписка останется в истории до конца срока хранения.

О переписке

Можно приложить до трёх фото PNG, JPEG или WebP по 5 МБ.

Переписка и фото хранятся 90 дней после последнего принятого сообщения. Преподаватель получит доступ к диалогу, когда вы попросите его помочь.

Проверка решения остаётся отдельным действием.