Глиф Учебники

Как выбрать первые 10 строк — LIMIT, TOP, FETCH FIRST

Справочник · SQL · 2 минуты чтения

В SQLite, MySQL, MariaDB и PostgreSQL первые 10 строк даёт LIMIT:

SQL
SELECT id, name, price
FROM products
ORDER BY price DESC
LIMIT 10;

LIMIT ставится в самом конце запроса, после ORDER BY. Без ORDER BY «первые» строки — какие попало: СУБД не обязана хранить и выдавать их в порядке добавления.

В разных СУБД

СУБДПервые 10 строк
SQLite, MySQL, MariaDB, PostgreSQLSELECT … ORDER BY … LIMIT 10
PostgreSQL, Oracle 12c и новее (стандарт SQL)SELECT … ORDER BY … FETCH FIRST 10 ROWS ONLY
Microsoft SQL ServerSELECT TOP 10 … ORDER BY …
Oracle до 12cWHERE ROWNUM <= 10

TOP пишется сразу после SELECT, а не в конце: SELECT TOP 10 id, name FROM products ORDER BY price DESC. SQLite не понимает ни TOP, ни FETCH FIRST — только LIMIT.

Последние 10 строк

Последние — это первые при обратной сортировке:

SQL
SELECT id, name FROM products ORDER BY id DESC LIMIT 10;

Если нужно показать их в прямом порядке, оберните запрос в подзапрос и отсортируйте ещё раз:

SQL
SELECT * FROM (
    SELECT id, name FROM products ORDER BY id DESC LIMIT 10
) AS last_rows
ORDER BY id;

Страницы: OFFSET

OFFSET пропускает строки. Страница 3 по 10 строк — строки с 21-й по 30-ю:

SQL
SELECT id, name FROM products ORDER BY id LIMIT 10 OFFSET 20;

Пропуск считается так: (номер страницы − 1) × размер страницы. В MySQL и SQLite есть и короткая запись LIMIT 20, 10 — сначала пропуск, потом число строк. Порядок легко перепутать, поэтому LIMIT … OFFSET … надёжнее.

На больших таблицах OFFSET 100000 медленный: СУБД всё равно читает и отбрасывает 100 000 строк. Для длинных списков листают «от последнего показанного»: WHERE id > 12345 ORDER BY id LIMIT 10.

Первые строки в каждой группе

Два самых дорогих товара в каждой категории — задача для оконной функции ROW_NUMBER() (SQLite 3.25 и новее, MySQL 8.0 и новее, PostgreSQL):

SQL
SELECT category, name, price
FROM (
    SELECT category, name, price,
           ROW_NUMBER() OVER (PARTITION BY category ORDER BY price DESC) AS n
    FROM products
) AS ranked
WHERE n <= 2
ORDER BY category, price DESC;
categorynameprice
КанцелярияПенал12
КанцелярияТетрадь3
СумкиРюкзак85
СумкиСумка для ноутбука70
ТехникаНаушники60
ТехникаКалькулятор30
УчёбаГлобус45

ROW_NUMBER() нумерует строки внутри каждой категории (PARTITION BY) по убыванию цены, а внешний запрос оставляет номера 1 и 2. Таблица — из учебной базы курса, см. урок Добавление строк.

Подводные камни