Урок 3 из 8 · 20 мин · обновлено

Сортировка, LIMIT, DISTINCT и вычисления в запросе

Как упорядочить результат через ORDER BY, взять первые строки с LIMIT и OFFSET, убрать повторы с DISTINCT и посчитать новый столбец прямо в запросе с понятным именем через AS.

ORDER BY: порядок строк

База хранит строки так, как ей удобно, и без сортировки не обещает никакого порядка. Сегодня строки придут по номеру, завтра — иначе. Если порядок важен, его задают явно через ORDER BY:

SQL
SELECT title, price FROM books ORDER BY price DESC;
Результат
title                             | price
Чистый код                        | 1200
Sapiens                           | 890
Краткая история времени           | 720
Гарри Поттер и философский камень | 650
Мастер и Маргарита                | 590
Хоббит                            | 540
Идиот                             | 480
Преступление и наказание          | 450
  • без указания направления, или со словом ASC, — по возрастанию;
  • DESC — по убыванию.

ORDER BY пишут после WHERE: сначала отобрали строки, потом расставили.

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

SQL
SELECT genre, title, price FROM books ORDER BY genre, price DESC;
Результат
genre   | title                             | price
IT      | Чистый код                        | 1200
наука   | Sapiens                           | 890
наука   | Краткая история времени           | 720
роман   | Мастер и Маргарита                | 590
роман   | Идиот                             | 480
роман   | Преступление и наказание          | 450
фэнтези | Гарри Поттер и философский камень | 650
фэнтези | Хоббит                            | 540

Жанры встали по алфавиту, а внутри каждого жанра книги идут от дорогой к дешёвой. Жанр IT оказался первым: при сортировке текста латинские буквы идут раньше русских.

LIMIT и OFFSET: только первые строки

Вопрос «три самые дорогие книги» решается в два шага: отсортировать по цене и взять три верхние строки. Второй шаг — LIMIT:

SQL
SELECT title, price FROM books ORDER BY price DESC LIMIT 3;
Результат
title                   | price
Чистый код              | 1200
Sapiens                 | 890
Краткая история времени | 720

OFFSET пропускает строки перед выдачей. Так устроены страницы каталога: первая страница — первые три книги, вторая — следующие три:

SQL
SELECT title, price FROM books ORDER BY price DESC LIMIT 3 OFFSET 3;
Результат
title                             | price
Гарри Поттер и философский камень | 650
Мастер и Маргарита                | 590
Хоббит                            | 540

LIMIT почти всегда идёт в паре с ORDER BY. Без сортировки «первые три» — это какие-то три строки, и при следующем запуске они могут оказаться другими.

Слово для ограничения строк зависит от базы:

База Как взять три строки
SQLite, PostgreSQL, MySQL LIMIT 3
Microsoft SQL Server SELECT TOP 3 …
Oracle, а также PostgreSQL FETCH FIRST 3 ROWS ONLY

DISTINCT: без повторов

Какие жанры вообще есть в магазине? Если выбрать столбец genre, жанр повторится у каждой книги. DISTINCT оставляет каждое значение один раз:

SQL
SELECT DISTINCT genre FROM books ORDER BY genre;
Результат
genre
IT
наука
роман
фэнтези

Если после DISTINCT перечислить несколько столбцов, повтором считается строка, где совпадают все они сразу.

Считаем прямо в запросе

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

SQL
SELECT title, price, price * 0.9 AS sale_price
FROM books ORDER BY price DESC LIMIT 3;
Результат
title                   | price | sale_price
Чистый код              | 1200  | 1080.0
Sapiens                 | 890   | 801.0
Краткая история времени | 720   | 648.0

AS даёт посчитанному столбцу имя. Без него столбец назывался бы price * 0.9, и в отчёте это выглядело бы странно. Запись .0 в конце значит, что результат — дробное число: целую цену умножили на дробь.

Важно: SELECT ничего не меняет в таблице. Цены в books остались прежними — скидка существует только в этом ответе.

Имена через AS пишите латиницей. Русское имя возможно, но его придётся брать в двойные кавычки — AS "цена со скидкой", — и не все программы с ним дружат.

Попробуйте сами. Покажите три самые дешёвые книги с ценами. Затем выведите список городов, где живут клиенты, — каждый город по одному разу и по алфавиту.

Решение

Самые дешёвые — сортировка по возрастанию и LIMIT:

SQL
SELECT title, price FROM books ORDER BY price LIMIT 3;
Результат
title                    | price
Преступление и наказание | 450
Идиот                    | 480
Хоббит                   | 540

Города без повторов:

SQL
SELECT DISTINCT city FROM customers ORDER BY city;
Результат
city
NULL
Казань
Москва
Пермь

Первой строкой стоит NULL — это незаполненный город Дины. В SQLite и MySQL пустые значения при сортировке по возрастанию идут первыми, в PostgreSQL — последними. Как с ними работать, разберём в следующем уроке.

Мини-тест: проверьте себя

Закрепите урок: несколько вопросов, разбор ответов — в конце.

  1. Что делает ORDER BY price DESC?

  2. Почему LIMIT 3 без ORDER BY не ответит на вопрос «три самые дорогие книги»?

  3. Что вернёт SELECT DISTINCT genre FROM books?

  4. Зачем в запросе SELECT title, price * 0.9 AS sale_price пишут AS sale_price?

  5. Какой запрос пропустит три самые дорогие книги и покажет следующие три?