SQL выбирает «окно» вокруг определенной строки - PullRequest
8 голосов
/ 29 декабря 2008

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

Я работаю над приложением для создания фотогалереи и хочу отобразить 9 миниатюр, отображающих контекст отображаемой текущей фотографии (в сетке 3x3 с текущей фотографией в центре, если текущая фотография не находится в первых 4 показываются фотографии, и в этом случае, например, если текущая фотография является второй, я хочу выбрать фотографии с 1 по 9). Например, дан альбом, содержащий список фотографий с идентификаторами:

1, 5, 9, 12, 13, 18, 19, 20, 21, 22, 23, 25, 26

Если текущее фото 19, я также хочу просмотреть:

9, 12, 13, 18, 19, 20, 21, 22, 23

Если текущее фото 5, я также хочу просмотреть:

1, 5, 9, 12, 13, 18, 19, 20, 21

Я думал о чем-то вроде:

SELECT *
FROM photos
WHERE ABS(id - currentphoto) < 5
ORDER BY id ASC 
LIMIT 25

но это не работает в случае, когда идентификаторы непоследовательны (как в примере выше), или в случае, когда перед текущей фотографией недостаточно фотографий.

Есть мысли?

Спасибо

Дом

p.s. Пожалуйста, оставьте комментарий, если что-то неясно, и я уточню вопрос. Если кто-то может придумать более полезный заголовок, чтобы помочь другим людям найти этот вопрос в будущем, пожалуйста, оставьте комментарий.

Ответы [ 3 ]

5 голосов
/ 29 декабря 2008

Вероятно, можно просто использовать UNION, а затем обрезать дополнительные результаты в процедурном коде, который отображает результаты (так как это вернет 20 строк в некраевых случаях):

(SELECT 
     * 
FROM photos
   WHERE ID < #current_id#
   ORDER BY ID DESC LIMIT 10)
UNION
  (SELECT *
   FROM photos
   WHERE ID >= #current_id#
   ORDER BY ID ASC LIMIT 10)
ORDER BY ID ASC

РЕДАКТИРОВАТЬ: Увеличено ограничение до 10 с обеих сторон СОЮЗА, как предложено le dorfier .

РЕДАКТИРОВАТЬ 2: Изменено, чтобы лучше отражать окончательную реализацию, как предложено Домиником.

1 голос
/ 29 декабря 2008

Если вы используете SQL Server, вы можете использовать функцию row_number (), чтобы получить индекс порядка строк, и сделать что-то вроде этого:

declare @selected_photo integer;
set @selected_photo = 5;

declare @buffer_size integer;
set @buffer_size = 2;

select
   ph.rownum,
   ph.id
from
   (select row_number() over (order by Id) as rownum, * from Photos) as ph
where
   ph.rownum between case
                         when @selected_photo - @buffer_size < 1 then 1
                         else @selected_photo - @buffer_size
                      end
                      and @selected_photo + @buffer_size

Edit: Вот статья о моделировании функции row_number () в MySQL, объединяющая это с это может дать вам то, что вам нужно - я бы попробовал, но у меня нет удобной базы данных MySQL для работы на работе. : -)

http://www.xaprb.com/blog/2006/12/02/how-to-number-rows-in-mysql/

0 голосов
/ 29 декабря 2008

Это стандартная проблема «упорядочения строк» ​​... Если ваша база данных имеет возможность rowId, вы можете использовать это, в противном случае вам нужен подзапрос, который подсчитывает количество строк с идентификаторами меньше, чем идентификатор текущей строки ... как это:

- при условии, что @Id является значением id в «середине»

 Select *  From Photos P
 Where (Select Count(*) From Photos
         Where id <= P.Id)
     Between (Select Count(*) From Photos
              Where id < @Id) - 4
        And  (Select Count(*) From Photos
              Where id < @Id) + 4

Когда в комментарии возникла проблема с альбомом, вы бы хотели добавить предикат альбома в каждый подзапрос

   Select *  From Photos P
   Where (Select Count(*) From Photos
          Where album = @album
            And id <= P.Id)
     Between (Select Case When Count(*) < 4 
                      Then 4 Else Count(*) End
              From Photos
              Where album = @album
                 And id < @Id) - 4
        And  (Select Case When Count(*) < 4 
                      Then 4 Else Count(*) End
              From Photos
              Where album = @album
                  And id < @Id) + 4
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...