SQL-запрос с JOIN - PullRequest
       2

SQL-запрос с JOIN

0 голосов
/ 03 июня 2018

Я создаю фильтр товаров для интернет-магазина.У меня есть таблица продуктов, таблица характеристик и таблица, в которой я храню product_id, характеристика_идентификатора и одно значение фильтра.

shop_products - идентификатор, имя

shop_characteristics - идентификатор, значения (json)

shop_values ​​ - идентификатор продукта, характеристический_идентификатор, значение

Я могу создать запрос, чтобы получить все продукты по одному значениювот так:

SELECT `p`.* FROM `shop_products` `p` 
LEFT JOIN `shop_values` `fv` ON `p`.`id` = `fv`.`product_id` 
WHERE ((`fv`.`characteristic_id`=3) AND (`fv`.`value`='outdoor'))

Работает нормально.Кроме того, я могу изменить этот запрос и получить все продукты по нескольким значениям, которые принадлежат к одной и той же группе характеристик (имеют идентичный идентификатор_идентификации), например:

SELECT `p`.* FROM `shop_products` `p` 
LEFT JOIN `shop_values` `fv` ON `p`.`id` = `fv`.`product_id` 
WHERE ((`fv`.`characteristic_id`=3) AND (`fv`.`value`='outdoor'))
OR ((`fv`.`characteristic_id`=3) AND (`fv`.`value`='indoor'))

, но при попытке создать запрос для несколькихусловия с различными характеристиками_идентификатора я ничего не получаю

SELECT `p`.* FROM `shop_products` `p` 
LEFT JOIN `shop_values` `fv` ON `p`.`id` = `fv`.`product_id` 
WHERE ((`fv`.`characteristic_id`=3) AND (`fv`.`value`='outdoor'))
AND ((`fv`.`characteristic_id`=5) AND (`fv`.`value`='white'))

Полагаю, это не работает из-за оператора AND, который в этом случае используется неправильно, поскольку в таблице shop_values ​​ нет записей, которыеимеют оба характеристики: 3 и 5.

Поэтому мой вопрос состоит в том, как объединить или изменить мой запрос, чтобы получить все связанные продукты, или, возможно, это недостаток для хранения таких данных, и мне нужно создать другой вид shop_values ​​ таблица?

1 Ответ

0 голосов
/ 03 июня 2018

Использовать агрегацию.Вы также можете использовать кортежи с предложением in.Итак:

SELECT p.*
FROM shop_products p JOIN
     shop_values v
     ON p.id = v.product_id
WHERE (v.characteristic_id, v.value) IN ( (3, 'outdoor'), (5, 'white'))
GROUP BY p.id
HAVING COUNT(DISTINCT v.characteristic_id) = 2;

Примечания:

  • Излишне экранирование псевдонимов столбцов и таблиц (с обратными галочками) просто затрудняет написание и чтение запроса.
  • ВВообще, использование SELECT p.* и GROUP BY p.id действительно очень плохая форма.Единственное исключение - когда вы группируете по уникальному или первичному ключу.Эта последняя форма фактически поддерживается в стандарте ANSI.
  • A LEFT JOIN не требуется.Вам нужно найти соответствия между таблицами, чтобы логика работала.
  • Использование AND и OR подходит для предложения WHERE.MySQL поддерживает кортежи с IN, что несколько упрощает логику.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...