MySQL选择连接多对多表加上IN和NOT IN
Posted
技术标签:
【中文标题】MySQL选择连接多对多表加上IN和NOT IN【英文标题】:MySQL select join many to many tables plus IN and NOT IN 【发布时间】:2012-09-27 21:45:54 【问题描述】:我有 3 个表:产品、标签和 products_tags(产品和标签之间的多对多)。 在我的架构中,一个产品可以有零到多个标签,一个标签可以有零到多个产品。 现在我想选择有特定标签而没有特定标签的产品。
产品表:
idproducts / 名称
1 / 三星银河
2/三星note1
3/三星note2
4 / iphone 4gs
标签表:
idtags / 单词
1 / 三星
2 / 星系
3 / 注释1
4 / note2
5 / iphone
6 / 4gs
7 / 苹果
Products_Tags 表:
产品/标签
1 / 1
1 / 2
2 / 1
2 / 3
3 / 1
3 / 4
4 / 5
4 / 6
我有下面的查询,但它给了我带有标签的产品,我不想要因为它们有一些其他标签,并且作为连接的结果,它们出现在结果集中。
选择 * FR0M 产品作为 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,并且我定义了像“三星”这样的标签,而没有“note1”和“note2”。对此的查询是什么?
附:我想也许应该使用 EXISTS 或 NOT EXISTS,但我只是不知道应该如何使用它们。
提前致谢
【问题讨论】:
【参考方案1】:您的查询不起作用,因为连接选择了所有带有 samsung 标签的元素,包括 samsung note 1
和 samsung note 2
。您可以使用group_concat
对所有标签名称进行分组,然后使用like
或Regexp
对其进行过滤,如下所示:
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'
一些重要资源:
Group_Concat Regexp【讨论】:
tnx Kasi,它现在可以工作了,但是除了正则表达式,我还有其他选择吗?我不熟悉它,如果可以的话,我更喜欢使用其他选项Regexp
将允许您将多个表达式组合在一起,但您也可以为此使用Like
,例如tagname not like '%note1%' and tagname not like '%note2%'
【参考方案2】:
您想要所有带有 samsung 或 mobile 标签但没有 note 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 子句的任何行都不可能满足 not in one。三星和手机都不是note1或note2
上面进行了一次连接以获取三星或移动设备,然后再次连接到标签表(使用不同的别名)以获取所有没有note1或note2标签的人。
【讨论】:
tnx Tony,但它仍然给了我我不想要的产品 'samsung note1' 和 'samsung note2' 使用您的查询,我得到了带有“三星”标签的全部 3 种产品。我需要排除带有我不想要的标签的产品,即使同一产品有一些我想要的标签。例如,即使产品“samsung note1”和“samsung note2”有标签“samsung”,但它们有标签“note1”和“note2”,我希望它们不在结果集中。我只想要有标签'samsung'但没有标签'note1'和'note2'的产品'samsung galaxy' Ahhhhhhhh,嗯,我得考虑一下这个以上是关于MySQL选择连接多对多表加上IN和NOT IN的主要内容,如果未能解决你的问题,请参考以下文章