@VanZan

Как выбрать ограниченное количество записей разного типа?

Есть таблица complex, которая содержит записи о жилых комплексах (ЖК). В ней есть поле class, которое содержит класс комфортности ЖК.

class = 1 -- эконом
class = 2 -- комфорт
class = 3 --бизнес
class = 4 -- премиум

Если отсортировать такую таблицу, скажем, по минимальной стоимости квартиры (price ASC), то вся выдача будут забита жилыми комплексами эконом класса.

В связи с этим, возникла задача при постраничной навигации выводить на страницу ограниченное количество записей каждого типа. Например: 3 эконома, 14 комфорта, 9 бизнеса, 4 премиум.

Не приложу ума, как это сделать средствами MySQL.
  • Вопрос задан
  • 70 просмотров
Решения вопроса 1
rozhnev
@rozhnev Куратор тега MySQL
Fullstack programmer, DBA, медленно, дорого
В MySQL, начиная с версии 8.0, вы можете использовать оконную функцию row_number():
select 
	class,
	price
from (
  select 
	  class,
	  price,
	  row_number() over (partition by class order by price) rn
  from complex
) prices
where 
	(class=1 and rn < 3) -- 2 econom
	or (class=2 and rn < 4) -- 3 comfort
	or (class=3 and rn < 2) -- 1 premium
;


Mysql online
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
alexey-m-ukolov
@alexey-m-ukolov Куратор тега MySQL
С точки зрения пользовательского интерфейса это полная хрень, конечно, но решается довольно легко - нужно просто сделать 4 запроса и не пытаться объять необъятное. Полученные данные объединяете в один массив и всё - страница готова.

А что вы будете делать, когда страницы с премиумом закончатся, а экономы ещё нет?

Если очень уж необходимо сделать именно так, то приемлемый пользовательский интерфейс в данном случае был бы таким: 4 отдельных таблицы, по одной для каждого типа, и под ними один на всех блок пагинации. В качестве количества страниц в нём используется максимальногое значение среди указанных типов. Когда для какого-то типа данные заканчиваются, выводится сообщение об этом, остальные таблицы рендерят данные. И в итоге у вас будет 4 пагинации на бэкенде и один контрол для них на фронте. Валить данные в одну таблицу, когда пользователь явно указал, что хочет сортировать по цене - это ад. Я ещё понимаю, была бы сначала сортировка по классу, а потом по цене, здесь был бы хоть какой-то смысл, хоть это и не то, чего хотел пользователь.
Ответ написан
@VitalyChaikin
Для каждой из четырех секций имеем запрос типа:
Select <список полей> From T Where class=1 and `условие_страницы` Order by `Поле_условия_страницы`

Чтобы была возможна пагинация, необходимо чтобы результат запроса был упорядочен;
`условие_страницы` вида `Поле_условия_страницы` > `Значения_Поля_условия_предыдущей_страницы`
Больше Или меньше зависит от общего направления сортировки результата
(надеюсь не слишком путанно)
Ответ написан
Комментировать
@Akina
Сетевой и системный админ, SQL-программист.
3 эконома, 14 комфорта, 9 бизнеса, 4 премиум.


Итого 3+14+9+4=30.

Теперь нумеруем каждый тип по отдельности (используем целочисленное деление с остатком).

Эконом - 1,2,3,31,32,33,61,62,63...
Комфорт - 4,5,..,16,17,34,35,...
Бизнес - 18,19,..25,26,48,49,...
Премиум - 27,28,29,30,57,58,...

И теперь сортируем при пагинации по этому номеру.

Оно, конечно, всё равно поплывёт, когда какой-то тип закончится - но хоть не с самого начала.

PS. Но вообще-то клиент, увидев на странице дикие скачки цен, и прыжки вверх-вниз между страницами, скорее всего закроет этот бред, чтобы мозг не поломался.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы