多对多选择仅具有完全相同标签的行

时间:2018-11-15 19:15:35

标签: mysql many-to-many

我有3个表:标签,产品和它们之间的关系表。 关系表看起来像这样:

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

用户可以选择两个选项“ 所有”或“ 其中一个”。

因此,如果用户选择了所有这些,则意味着产品必须完全具有用户选择的所有标签。

因此,如果用户选择ID为 1 2 的标签,则应仅选择ID为 1 的产品,因为此产品具有用户选择的完全相同的标签。 (另一种方法是,如果用户选择ID为 2 的标签,则应仅选择ID为 9 的产品。)

因此,产品必须具有用户选择的所有标签(不多也不少)。

我已经为以下任何一项/其中一项拥有的SQL:

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 :(得分:0)

您可以在GROUP BYProductID,并在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

答案 1 :(得分:0)

(所有条件下)您要寻找的吗?

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';