Как вернуть элементы для 1 конкретного значения и всех других элементов с левым соединением, не удваивая в MySQL? - PullRequest
0 голосов
/ 14 июня 2019

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

У меня есть три таблицы:

item_crawls
---------------
id
item_id
units_sold
current_price


items
------------
id
item_title


favorites
-----------
id
product_id
user_id

Таблица item_crawls - это запись перемещений элементов, т.е.изменения цен, проданные единицы со временем.Таблица item_crawls относится к таблице элементов в отношении «один ко многим».

Таблица избранного предназначена для записи пользователями своих любимых элементов.Таблица избранного связана с таблицей элементов в отношении «один ко многим».В таблице избранного комбинация product_id / user_id допускается только один раз.

Таблица элементов является базовой таблицей для элементов.Элемент может появиться только один раз в таблице элементов.

У меня есть этот запрос:

SELECT SQL_CALC_FOUND_ROWS distinct item_id as itemid , 
favorites.id as faveid , items.item_title as itemtitle, 
MAX(item_crawls.units_sold) as sold, 
ROUND(AVG(item_crawls.current_price),2) as aveprice from item_crawls 
INNER JOIN items on items.id = item_crawls.item_id left join favorites 
on favorites.product_id = items.id where item_crawls.units_sold > 1 
AND item_crawls.units_sold <= 500 
AND MATCH(items.item_title) AGAINST ('*cab*' IN BOOLEAN MODE) 
AND favorites.user_id = 1 group by item_crawls.item_id , faveid 
ORDER BY sold DESC limit 0,5

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

Например, если в таблице элементов 10 элементов с item_title 'cable', и пользователь с идентификатором 1 выбрал 2из этих предметов я хочу вернуть все 10 предметов, а также возвращать избранное.id для двух избранных предметов.Оставшиеся 8 непривилегированных товаров все равно должны быть возвращены, но с значением fav.id NULL.

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

Проблемы:

  1. Если в предложении WHERE я укажу Favorites.user_id = 1, он возвращает только те элементы, которые понравились пользователю 1, а не возвращает все.
  2. Если я не укажу Favorites.user_id, то запрос удваивает количество элементов, которые были добавлены другими пользователями.Так, например, если пользователи 1, 2 и 3 добавили в избранное элемент, то запрос будет возвращать один и тот же элемент 3 раза вместе с одиночными строками оставшихся непривилегированных совпадений.

Есть ли способ достичь этого с помощью одного запроса, преодолев при этом 2 вышеупомянутые проблемы?

Я не хочу выполнять начальный запрос для поиска элемента, а затем выполнять циклические запросы по результатам, чтобы проверить, выбрал ли пользователь элемент, поскольку это очень неэффективно.

Спасибо за внимание!

1 Ответ

0 голосов
/ 14 июня 2019

Вы можете переместить проверку user_id в критерии объединения, чтобы она не распространялась на весь набор результатов:

LEFT JOIN favorites ON favorites.product_id = items.id AND favorites.user_id = 1

Чтобы сохранить его в предложении WHERE, было бы:

(favorites.id IS NULL OR favorites.user_id = 1)

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

CASE WHEN favorites.id IS NULL THEN 0 ELSE 1 END AS favorite,

Кроме того, похоже, что вам также нужно группировать по itemtitle, и я сомневаюсь, что вам нужно отдельное ключевое слово, если ваши отношения навязаны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...