多对多只选择具有完全相同标记的行

yqkkidmi  于 2021-06-19  发布在  Mysql
关注(0)|答案(2)|浏览(245)

我有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我决定使用哪个查询。

7bsow1i6

7bsow1i61#

你可以 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
2cmtqfgy

2cmtqfgy2#

这是你要找的东西吗?

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

相关问题