Урок 3 из 8 · 20 мин · обновлено
Сортировка, LIMIT, DISTINCT и вычисления в запросе
Как упорядочить результат через ORDER BY, взять первые строки с LIMIT и OFFSET, убрать повторы с DISTINCT и посчитать новый столбец прямо в запросе с понятным именем через AS.
ORDER BY: порядок строк
База хранит строки так, как ей удобно, и без сортировки не обещает никакого порядка. Сегодня строки придут по номеру, завтра — иначе. Если порядок важен, его задают явно через ORDER BY:
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: сначала отобрали строки, потом расставили.
Столбцов для сортировки может быть несколько. Первый задаёт основной порядок, второй работает внутри одинаковых значений первого:
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:
SELECT title, price FROM books ORDER BY price DESC LIMIT 3;
title | price
Чистый код | 1200
Sapiens | 890
Краткая история времени | 720
OFFSET пропускает строки перед выдачей. Так устроены страницы каталога: первая страница — первые три книги, вторая — следующие три:
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 оставляет каждое значение один раз:
SELECT DISTINCT genre FROM books ORDER BY genre;
genre
IT
наука
роман
фэнтези
Если после DISTINCT перечислить несколько столбцов, повтором считается строка, где совпадают все они сразу.
Считаем прямо в запросе
В SELECT можно не только перечислять столбцы, но и считать: складывать, умножать, делить. Покажем цену со скидкой 10% для трёх самых дорогих книг:
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:
SELECT title, price FROM books ORDER BY price LIMIT 3;
title | price
Преступление и наказание | 450
Идиот | 480
Хоббит | 540
Города без повторов:
SELECT DISTINCT city FROM customers ORDER BY city;
city
NULL
Казань
Москва
Пермь
Первой строкой стоит NULL — это незаполненный город Дины. В SQLite и MySQL пустые значения при сортировке по возрастанию идут первыми, в PostgreSQL — последними. Как с ними работать, разберём в следующем уроке.
Мини-тест: проверьте себя
Закрепите урок: несколько вопросов, разбор ответов — в конце.
-
Что делает ORDER BY price DESC?
ORDER BY задаёт порядок, а DESC — направление «по убыванию». Без DESC сортировка идёт по возрастанию.
-
Почему LIMIT 3 без ORDER BY не ответит на вопрос «три самые дорогие книги»?
Порядок строк без ORDER BY не гарантирован. Сначала строки сортируют по цене, а LIMIT берёт верхние.
-
Что вернёт SELECT DISTINCT genre FROM books?
DISTINCT убирает повторы из результата: восемь книг, но жанров всего четыре.
-
Зачем в запросе SELECT title, price * 0.9 AS sale_price пишут AS sale_price?
AS только называет столбец в ответе. Таблица при этом не меняется — запрос SELECT ничего не записывает.
-
Какой запрос пропустит три самые дорогие книги и покажет следующие три?
OFFSET 3 пропускает первые три строки отсортированного результата, LIMIT 3 берёт следующие три. Так устроены страницы каталога.