У меня есть таблица product
с полями, такими как title
(varchar) или availability
(bool).INNER JOIN with NOT IN возвращает неправильные результаты
Пользователь может искать продукты по названию (product.title
), но также может применять определенные фильтры (такие как тип, производитель и т. Д.). Я решил это, используя SELECT
рядом с INNER JOIN
. Пример сгенерированного запроса выглядит так:
SELECT z.*
FROM product z
WHERE (z.title LIKE "%bread%")
AND z.availability = 1
AND z.category IN (4,5,6);
Это работает отлично. Тем не менее, продукты также маркируются «тегами аллергии» (например, клейковины). К сожалению, продукт может содержать любое количество «аллергии тегов», таким образом, я должен был использовать сшивающий таблицу (crosslink__productXproduct_allergy_tag
):
id int not null primary key auto_increment
productId int
allergyTagID int
теги хранятся в таблице product_allergy_tag
, используя идентификатор в качестве первичного ключа, и название тега. Естественно, что при поиске продуктов, которые являются глютен, сгенерированный запрос будет выглядеть следующим образом:
SELECT z.*
FROM product z
INNER JOIN crosslink__productXproduct_allergy_tag a ON z.id = a.productId
WHERE (z.title LIKE "%bread%")
AND z.availability = 1
AND a.allergyTagId IN (15)
(С 15 является идентификатор глютена тега).
Однако, если я управлял поиском таким же образом, как показано выше, поиск глютен продуктов будет в конечном итоге показывает только продукты, которые содержат клейковину.
Так что я подумал: я просто нужно обратить логику:
Вместо:
a.allergyTagId IN (15)
было бы:
a.allergyTagId NOT IN (15)
Но тем не менее, по причинам, я не понимаю , запрос по-прежнему возвращает некоторые продукты с этим тегом аллергии, хотя он не возвращает все из них.
Я попытался понять суть этого, тестируя различные варианты и сравнивая результаты, но безрезультатно.
Ходят слухи, что я не SQL-класс.
Любая поддержка по этому вопросу была бы полезна. Спасибо!
Ваш запрос возвращает все продукты, для которых существует аллерген, который не является клейковиной. Это не вернет ничего без аллергенов, он будет возвращать продукты с несколькими аллергенами более одного раза, и он все равно будет возвращать клейковину, если у них также есть второй (или третий) аллерген. – Thilo
Поскольку вы делаете внутреннее соединение в crosslink__productXproduct_allergy_tag. Вы выбираете из таблицы продуктов с каким-то аллергеном. Затем вы сужаетесь к тем, у кого есть «хлеб» в названии, доступен и что аллергия не является клейковиной. Так как некоторые продукты могут иметь несколько аллергенов, вы, по сути дела, присоединяетесь к случайному приходу продукта, часто это не будет клейковиной, и поэтому он будет выбран. Ясно, что это полностью назад от того, что вам нужно. Я предлагаю начать снова, делая логические объединения и рассматривая эффект каждого добавления. –