Разбивка на страницы с объединением и двумя подзапросами

#mysql

#mysql

Вопрос:

Мне нужен совет, чтобы сделать запрос для поиска 5 рекомендуемых продуктов на каждой странице (мне нужно отобразить одиннадцать на страницу, 5 рекомендуемых продуктов и 6 обычных), я пробовал с объединением, но когда я меняю внешний предел на ОГРАНИЧЕНИЕ 5 СМЕЩЕНИЕ 5 (страница 2), рекомендуемых продуктов нетпоказал, есть ли что-то, чего мне не хватает?

Я пробовал этот запрос:

 SELECT * FROM ( 
              (SELECT a.id, concat(city.description, '-', department.description) as location, a.featured, a.price, a.title, a.description   FROM ads a
              LEFT JOIN city on a.city_id =  city.id
              LEFT JOIN department on city.department_id = department.id
              WHERE featured = true  order by a.price limit 5 offset 0)
              union all        
              SELECT a.id, concat(city.description, '-', department.description) as location, a.featured, a.price, a.title, a.description FROM ads a
              LEFT JOIN city on a.city_id =  city.id
              LEFT JOIN department on city.department_id = department.id
              WHERE featured = false
 ) as a            
 ORDER BY featured desc LIMIT 11 OFFSET 0
  

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

Комментарии:

1. ограничение / смещение не являются детерминированными без и ORDER BY

2. @danblack вы правы, я отредактировал запрос, но результат тот же

3. Вы хотите видеть 5 записей на страницу, или 6 записей на страницу, или 11 записей на страницу?

4. привет @zedfox, мне всегда нужно 5 избранных на страницу, но 6 обычных продуктов на страницу, всего 11

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

Ответ №1:

Попробуйте это. Это объединит ваши 5 рекомендуемых и 6 не рекомендуемых продуктов и установит приоритет для рекомендуемых и упорядочит их по признакам в первую очередь. Ваше приложение может взять первые 5 результатов и отобразить их в верхней части каждой страницы.

 select * from (
    SELECT 1 as priority, a.id, concat(city.description, '-', department.description) as location, a.featured, a.price, a.title, a.description
    FROM ads a
    LEFT JOIN city on a.city_id =  city.id
    LEFT JOIN department on city.department_id = department.id
    WHERE featured = true
    ORDER BY a.price
    LIMIT 5 offset 0
) x
union all
select * from (
    SELECT 2 as priority, a.id, concat(city.description, '-', department.description) as location, a.featured, a.price, a.title, a.description
    FROM ads a
    LEFT JOIN city on a.city_id =  city.id
    LEFT JOIN department on city.department_id = department.id
    WHERE featured = false
    ORDER BY a.price
    LIMIT 6 offset 0
) y
order by priority
  

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

Если у вас меньше рекомендуемых продуктов и вы хотите заменить рекомендуемые продукты

Если у вас меньше 5 избранных элементов, вы должны отслеживать это в переменной. Затем запустите:

 select * from (
    SELECT 1 as priority, a.id, concat(city.description, '-', department.description) as location, a.featured, a.price, a.title, a.description
    FROM ads a
    LEFT JOIN city on a.city_id =  city.id
    LEFT JOIN department on city.department_id = department.id
    WHERE featured = false
    ORDER BY a.price
    LIMIT 5 - <ENTER-YOUR-VARIABLE-HERE> offset 0
) y
  

Объедините рекомендуемые продукты с замененными не рекомендуемыми продуктами, чтобы получить 5 элементов.

Затем запустите последний запрос, чтобы получить 6 неустановленных продуктов:

 select * from (
    SELECT 2 as priority, a.id, concat(city.description, '-', department.description) as location, a.featured, a.price, a.title, a.description
    FROM ads a
    LEFT JOIN city on a.city_id =  city.id
    LEFT JOIN department on city.department_id = department.id
    WHERE featured = false
    ORDER BY a.price
    LIMIT 6 offset 0
) y
  

Если у вас меньше рекомендуемых продуктов и вы НЕ хотите заменять рекомендуемые продукты

Если у вас меньше 5 избранных элементов (скажем, всего 3), вы должны отслеживать это в переменной. Затем запустите:

 select * from (
    SELECT 2 as priority, a.id, concat(city.description, '-', department.description) as location, a.featured, a.price, a.title, a.description
    FROM ads a
    LEFT JOIN city on a.city_id =  city.id
    LEFT JOIN department on city.department_id = department.id
    WHERE featured = false
    ORDER BY a.price
    LIMIT 11 - <ENTER-YOUR-VARIABLE-HERE> offset 0
) y
  

Комментарии:

1. Привет, большое спасибо за вашу помощь, вот что-то еще, взятое из вашего примера, если не хватает рекомендуемых продуктов, как я могу заполнить результат нормалями, я имею в виду, если только будет указано 3, тогда мне нужно 8 нормальных для заполнения 11 записей, у вас есть какой-нибудь совет? Спасибо

2. @EduarDev добавил рекомендацию о том, как вы будете заполнять 11 записей

3. Мне было приятно @EduarDev.