MySQL选择连接多个表加上IN和NOT IN

时间:2012-09-27 21:45:54

标签: mysql join exists

我有3个表:Products,Tags和products_tags(产品和标签之间的多对多)。 在我的架构中,产品可以包含零到多个标签,标签可以包含零到多个产品。 现在我想选择具有特定标签且没有特定标签的产品。

产品表:

  

idproducts / name

     

1 / samsung galaxy

     

2 / samsung note1

     

3 / samsung note2

     

4 / iphone 4gs

标签表:

  

idtags / word

     

1 / samsung

     

2 / galaxy

     

3 / note1

     

4 / note2

     

5 / iphone

     

6 / 4gs

     

7 / apple

Products_Tags表:

  

产品/标签

     

1/1

     

1/2

     

2/1

     

2/3

     

3/1

     

3/4

     

4/5

     

4/6

我有下面的查询,但是它给了我带有标签的产品i 没有想要因为他们有其他标签而且由于加入它们会出现在结果集中。

  

SELECT * FR0M产品AS p

JOIN products_tags AS pt ON pt.product = p.idproducts

JOIN tags AS t ON t.idtags = pt.tag

WHERE t.word IN ('samsung', 'mobile')

AND t.word NOT IN ('note1', 'note2')

如果我想要三星Galaxy并且我定义了像'samsung'这样的标签而没有'note1'和'note2'。对此有什么疑问?

P.S。我想也许应该使用EXISTS或NOT EXISTS,但我只是无法弄清楚我应该如何使用它们。

先谢谢

2 个答案:

答案 0 :(得分:1)

您的查询无效,因为联接会选择包含标记三星的所有元素,包括samsung note 1samsung note 2。您可以使用group_concat对所有代码名称进行分组,然后使用likeRegexp对其进行过滤,如下所示:

select *, GROUP_CONCAT(t.word) tagname from products as p
  inner JOIN products_tags AS pt ON pt.products = p.productid
  inner Join tags t on t.idtags = pt.tags 
group by p.productid
having tagname not REGEXP 'note1|note2' 
   and tagname REGEXP 'samsung|mobile'

一些重要资源:

答案 1 :(得分:0)

您希望所有产品都带有三星或手机标签,但没有备注1或note2标签?

SELECT * FR0M products AS p

JOIN products_tags AS pt ON pt.product = p.idproducts

JOIN tags AS tp ON tp.idtags = pt.tag and (tp.word = 'samsung' or tp.word = 'mobile')

JOIN tags AS tn ON tn.idtags = pt.tag and tn.word <> 'note1' and tn.word <> 'note2'

将是一种方式。

你的尝试不起作用,因为任何满足in子句的行都不可能满足于一个。三星和手机都不是note1或note2

上面有一个连接来获取三星或移动设备,然后再次加入标签表(使用不同的别名)来获取没有note1或note2标签的所有那些。