Как распределить записи по столбцам
У меня есть таблица, хранящая конкурсные работы. Участники должны ввести текст и могут дополнительно загрузить фотографию
Когда я показываю записи на странице, я пролистываю страницы по 9 за раз.
Как я могу максимально гарантировать, что каждая страница содержит по крайней мере одну запись с фотографией на ней (предполагая, что есть достаточно фотографий для одной на странице)? Вероятно, было бы достаточно равномерно распределить записи с фотографиями по страницам
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