Как выбрать предыдущую и следующую запись в 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;

Как это работает:

Советы по оптимизации запросов для высоких нагрузок (highload):