Как выбрать предыдущую и следующую запись в MySQL по ID
При разработке веб-сайтов часто возникает задача сделать постраничную навигацию (пагинацию) или ссылки на «следующую» и «предыдущую» статьи. Самый надежный способ сделать это в СУБД MySQL — выборка соседних строк относительно текущего ID, url и т.д. Ниже приведены два эффективных решения: для старых и новых версий MySQL.
Способ 1. Универсальный запрос через UNION (для всех версий MySQL)
Этот метод идеально подходит, если в таблице есть «дыры» (пропущенные ID после удаления записей). Запрос гарантированно найдет ближайшие существующие строки.
(SELECT * FROM `your_table` WHERE `id` < 12 ORDER BY `id` DESC LIMIT 1)
UNION ALL
(SELECT * FROM `your_table` WHERE `id` > 12 ORDER BY `id` ASC LIMIT 1);
Как это работает: первая часть ищет ближайший меньший идентификатор, вторая — ближайший больший. Использование UNION ALL ускоряет выполнение, так как серверу не нужно тратить ресурсы на поиск и удаление дубликатов.
Способ 2. Оконные функции LAG и LEAD (для MySQL 8.0+)
Если у вас MySQL 8.0 и выше, лучше использовать стандартные оконные функции LAG и LEAD. Они позволяют получить значения из соседних строк в один проход:
SELECT * FROM (
SELECT *,
LAG(id, 1) OVER (ORDER BY id) AS prev_id,
LEAD(id, 1) OVER (ORDER BY id) AS next_id
FROM `your_table`
) AS subquery
WHERE subquery.id = 12;
Как это работает:
- LAG(поле, 1) — берет значение из указанного поля на 1 строку назад.
- LEAD(поле, 1) — берет значение из указанного поля на 1 строку вперед.
- В блоке OVER (ORDER BY …) обязательно нужно указать колонку, по которой определяется порядок строк.
- Если нужно добавить дополнительное условие, допишите его после
FROM `your_table`.
Советы по оптимизации запросов для высоких нагрузок (highload):
- Индексация: Поле
idобязательно должно быть первичным ключом (PRIMARY KEY) или иметь индекс (INDEX). Без этого поискid < 12вызовет полное сканирование таблицы (Full Table Scan), что затормозит сайт при росте базы данных. - Выборка полей: Избегайте конструкции
SELECT *в конечном коде. Заменяйте её на конкретные имена столбцов (например,SELECT id, title, slug), чтобы снизить нагрузку на сеть и оперативную память.

