Ответ
В SQL OFFSET — это ключевое слово, используемое в предложении LIMIT для указания количества строк, которые нужно пропустить перед началом возврата результатов из запроса. Это основа для реализации постраничной навигации (пагинации).
Синтаксис:
SELECT * FROM `products`
ORDER BY `created_at` DESC
LIMIT 10 OFFSET 20; -- Пропустить 20 строк, вернуть следующие 10
Эквивалентная запись (более распространенная):
SELECT * FROM `products`
ORDER BY `created_at` DESC
LIMIT 20, 10; -- LIMIT offset, row_count (пропустить 20, взять 10)
Практический пример пагинации на PHP/PDO:
$itemsPerPage = 10;
$page = (int) ($_GET['page'] ?? 1);
$offset = ($page - 1) * $itemsPerPage;
$stmt = $pdo->prepare("SELECT id, name, price FROM products LIMIT :limit OFFSET :offset");
$stmt->bindValue(':limit', $itemsPerPage, PDO::PARAM_INT);
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->execute();
$products = $stmt->fetchAll();
Важные замечания:
- Производительность: На больших
OFFSET(например, 10000) запрос может работать медленно, так как СУБД все равно должна отсчитать пропускаемые строки. Для глубокой пагинации лучше использовать ключи (WHERE id > :last_id). - Совместимость:
LIMIT X OFFSET Y— стандартный SQL, в то время какLIMIT Y, X— синтаксис MySQL. - Использование с
ORDER BY: Всегда используйтеOFFSETвместе сORDER BY, иначе порядок строк не гарантирован, и пагинация будет некорректной.
Ответ 18+ 🔞
А, ну это же про тот самый OFFSET! Ну, знаешь, такая штука, когда тебе надо не с начала таблицы данные тащить, а типа "перемотать" немного. Представь, что ты в кино — сидишь, смотришь, а потом вдруг захотел с середины фильма начать. Вот OFFSET это и есть — пропустить первые N записей, ёпта.
Синтаксис, блядь, простой:
SELECT * FROM `products`
ORDER BY `created_at` DESC
LIMIT 10 OFFSET 20; -- Пропустить 20 строк, вернуть следующие 10
Но есть ещё один способ, который народ чаще использует, типа сокращённый:
SELECT * FROM `products`
ORDER BY `created_at` DESC
LIMIT 20, 10; -- Тут сначала offset, потом limit! Не перепутай, а то нихуя не поймёшь потом.
Вот тебе живой пример на PHP, как это на сайте пагинацию делать:
$itemsPerPage = 10;
$page = (int) ($_GET['page'] ?? 1); // С какой страницы начинаем, если не указали — с первой
$offset = ($page - 1) * $itemsPerPage; // Вот тут магия! Высчитываем, сколько строк пролистать.
$stmt = $pdo->prepare("SELECT id, name, price FROM products LIMIT :limit OFFSET :offset");
$stmt->bindValue(':limit', $itemsPerPage, PDO::PARAM_INT);
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->execute();
$products = $stmt->fetchAll();
А теперь, чувак, держи важные моменты, про которые все забывают:
- Производительность, ёб твою мать! Если ты делаешь
OFFSETна 100 тысяч строк, то база всё равно их все посчитает и пропустит, прежде чем вернуть тебе следующие 10. Это пиздец как медленно на больших объёмах. Для глубоких страниц есть трюки — например, искать не по offset, а по ID последней записи на предыдущей странице (WHERE id > :last_id). - Совместимость: Первый вариант (
LIMIT ... OFFSET ...) — это как бы стандарт. А второй (LIMIT offset, limit) — это такой MySQL-специфичный прикол. На других базах может не зайти. - ORDER BY — святое дело! Никогда, блядь, не используй пагинацию без
ORDER BY. Иначе порядок строк будет плавать как говно в проруби, и сегодня ты на второй странице увидишь одни записи, а завтра — уже другие. Доверия к таким данным — ноль ебать.