Получить две следующие и две предыдущие записи в одном запросе SQL

Я хочу отобразить галерею изображений, и на странице просмотра должна быть возможность взглянуть на кучу миниатюр: текущее изображение с двумя предыдущими записями и двумя следующими.

Проблема получения двух next / prev в том, что я не могу (если не ошибаюсь) выбрать что-то вроде MAX (id) WHERE idxx.

Любая идея?

примечание: конечно, идентификаторы не следуют, поскольку они должны быть результатом нескольких экземпляров WHERE.

Спасибо Маршалл

ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
2
0
864
4

Ответы 4

Если вас просто интересуют предыдущая и следующая записи по идентификатору, не могли бы вы просто иметь предложение where, которое ограничивает WHERE id = xx, xx-1, xx-1, xx + 1, xx + 2, используя несколько предложений WHERE или используя В КОТОРОЙ ?

Это могло бы работать в идеальном мире, где у вас есть непрерывный столбец идентификаторов, но иногда возникают пробелы (неудачные вставки, удаления и т. д.). Я обнаружил, что лучше использовать TOP x в сочетании с WHERE, чтобы получить самые близкие.

Jeremiah Peschka 02.01.2009 15:30

если ваши идентификаторы непрерывны, вы можете сделать

where id >= @id-2 and id <= @id+2

В противном случае, я думаю, вам придется выполнить union 3 запроса, один для получения записи с заданным идентификатором, а два других возятся с top и order by, как это

select *
from table
where id = @id

union

select top 2 *
from table
where id < @id
order by id desc

union

select top 2 *
from table
where id > @id
order by id

Производительность будет не такой уж плохой, поскольку вы не получаете массивные наборы данных, но она не будет хорошей из-за использования union.

Если вы обнаружите, что производительность начинает быть проблемой, вы можете добавить столбцы для хранения идентификаторов предыдущего и следующего элементов; вычисление идентификаторов с помощью триггера или ночного процесса или чего-то еще. Это будет означать, что вы выполняете жесткий запрос только один раз, а не каждый раз, когда он вам нужен.

NB: «TOP 2» - это проприетарный синтаксис Microsoft / Sybase, не поддерживаемый MySQL. Вместо этого MySQL использует необязательное предложение LIMIT, которое появляется после предложения ORDER BY.

Bill Karwin 03.01.2009 00:20

Вам придется простить имена переменных в стиле SQL Server, я не помню, как MySQL выполняет именование переменных.

SELECT *
  FROM photos
 WHERE photo_id = @current_photo_id
 UNION ALL
SELECT *
  FROM photos
 WHERE photo_id > @current_photo_id
 ORDER BY photo_id ASC
 LIMIT 2
 UNION ALL
SELECT *
  FROM photos
 WHERE photo_id < @current_photo_id
 ORDER BY photo_id DESC
 LIMIT 2;

В этом запросе предполагается, что у вас могут быть несмежные идентификаторы. Однако в конечном итоге это может стать проблематичным, если у вас много фотографий в вашей таблице, поскольку TOP часто оценивается после, весь набор результатов был получен из базы данных. YMMV.

В сценарии с высокой нагрузкой я, вероятно, использовал бы эти запросы, но я бы также регулярно их прематериализировал, чтобы каждая фотография имела столбец PreviousPhotoOne, PreviousPhotoTwo и т. д. Это немного больше обслуживания, но оно хорошо работает, когда у вас много статических данных и вам нужна производительность.

Я думаю, что этот метод должен работать нормально для несмежных идентификаторов и должен быть более эффективным, чем использование UNION. currentID может быть установлен либо с использованием константы в SQL, либо путем передачи из вашей программы.

SELECT * FROM photos WHERE ID = currentID OR ID IN (
    SELECT ID FROM photos WHERE ID < currentID ORDER BY ID DESC LIMIT 2
) OR ID IN (
    SELECT ID FROM photos WHERE ID > currentID ORDER BY ID ASC LIMIT 2
) ORDER BY ID ASC

Разве вы не должны использовать OR вместо AND для предложения WHERE?

Tom H 02.01.2009 18:40

Другие вопросы по теме