Многие ко многим выбирают только строки с одинаковыми тегами - PullRequest
0 голосов
/ 15 ноября 2018

У меня есть 3 таблицы: теги, продукты и таблица отношений между ними. Например, таблица отношений выглядит следующим образом:

tagId | ProductId
  1   |    1
  2   |    1
  2   |    9

Пользователь может выбрать две опции: " Все эти " или " Одна из этих ".

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

Таким образом, если пользователь выбирает теги с идентификатором 1 и 2 , он должен выбирать только продукт с идентификатором 1 , поскольку этот продукт имеет в точности те же теги , которые выбрал пользователь. (Другой способ - если пользователь выбирает тег с идентификатором 2 , он должен выбирать только продукт с идентификатором 9 .)

Итак, продукт должен иметь все теги, которые выбрал пользователь (не больше, не меньше).

SQL, который у меня уже есть для Any / One из них:

SELECT DISTINCT s.SKU 
FROM SKUToEAN as s 
LEFT JOIN ProductDetails as p ON s.ProductDetailID=p.id 
JOIN ProductTagRelation as ptr ON (ptr.productId=p.id and ptr.tagId IN(Ids of selected tags))

Пример поведения:

TagId = 1 it should select => None
TagId = 2 it should select => 9
TagId = 1,2 it should select = 1,9

Так что, вероятно, мне нужно два запроса. Один для любого / один из них (у меня уже есть этот) и второй для всех этих. С помощью PHP я решаю, какой запрос использовать.

Ответы [ 2 ]

0 голосов
/ 15 ноября 2018

Это вы ищете (для всех условий)?

select product.id
from products
inner join <table> on products.id = <table>.productId
group by product.id
having group_concat(<table>.tagId order by <table>.tagId separator ',') = '1,2';
0 голосов
/ 15 ноября 2018

Вы можете GROUP BY на ProductID и использовать фильтрацию на основе условного агрегирования внутри предложения Having.MySQL автоматически преобразует логические значения в 0/1 при использовании в числовом контексте.Таким образом, чтобы иметь конкретное значение tagID, доступное для ProductID, его SUM(tagId = ..) должно быть 1 .

Все из них:

SELECT ptr.productId, s.SKU 
FROM SKUToEAN AS s 
LEFT JOIN ProductDetails AS p 
  ON p.id = s.ProductDetailID 
JOIN ProductTagRelation AS ptr 
  ON ptr.productId = p.id 
GROUP BY ptr.productId, s.SKU 
HAVING SUM(ptr.tagID = 1) AND -- 1 should be there
       SUM(ptr.tagID = 2) AND -- 2 should be there
       NOT SUM(ptr.tagID NOT IN (1,2)) -- other than 1,2 should not be there
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...