Как распределить записи по столбцам


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

Когда я показываю записи на странице, я пролистываю страницы по 9 за раз.

Как я могу максимально гарантировать, что каждая страница содержит по крайней мере одну запись с фотографией на ней (предполагая, что есть достаточно фотографий для одной на странице)? Вероятно, было бы достаточно равномерно распределить записи с фотографиями по страницам

3 3

3 ответа:

Это был один из самых сложных вопросов, которые я видел в последнее время-Спасибо за это! Я не могу заставить его работать с помощью одного оператора SQL, но я смог заставить его работать (по крайней мере, так кажется). В основном он пытается определить, сколько результатов будет возвращено, а затем, сколько из них имеют фотографии, и использует процент фотографий, разделенный на количество страниц (используя потолок, чтобы обеспечить по крайней мере один для первых нескольких страниц).

Во всяком случае, здесь идет:

SET @page = 1;
SET @resultsPerPage = 9;

SELECT @recCount:= COUNT(Id) as RecCount
FROM Entries;

SELECT @photoCount:= COUNT(Photo) as PhotoCount
FROM Entries
WHERE Photo IS NOT NULL;

SET @pageCount = CEILING(@recCount/@resultsPerPage);
SET @photosPerPage = CEILING(@photoCount/@pageCount);
SET @nonPhotosPerPage = @resultsPerPage - CEILING(@photosPerPage);

SELECT *
FROM (
      SELECT *, 
        @rownum := @rownum + 1 row_number
      FROM Entries JOIN    (SELECT @rownum := 0) r
      WHERE Photo IS NOT NULL
   ) a 
WHERE a.row_number > (@photosPerPage*(@page-1))
   and a.row_number <= (@photosPerPage*(@page))
UNION 
SELECT *
FROM (
      SELECT *, 
        @rownum2 := @rownum2 + 1 row_number
      FROM Entries JOIN    (SELECT @rownum2 := 0) r
      WHERE Photo IS NULL
   ) b
WHERE b.row_number > (@nonPhotosPerPage*(@page-1))
   and b.row_number <= (@nonPhotosPerPage*(@page))

Искрипка SQL .

Удачи вам!

Я бы предложил вам случайным образом упорядочить строки:

order by rand()
Это не гарантирует наличие фотографии на каждой странице, но помогает.

Альтернативой является сделать что-то вроде этого:

select *, @seqnum:=@seqnum+1
from t
where nophoto
select *, @seqnum:=@seqnum+8
from t
where photo

Затем отсортируйте по seqnum. Что делает это громоздким, так это обработка случаев, когда на странице меньше одной фотографии и больше одной фотографии. Случайный метод, вероятно, достаточен.

Для каждой страницы сделайте следующее (например, для страницы 3, размер страницы 10):

select ...
from ...
where has_photo
order by created
limit 3, 1
union
select ...
from ...
where not has_photo
order by created
limit 27, 9
Этот запрос разбивает два типа строк на два отдельных запроса, рекомбинированных объединением.