简体   繁体   English

Mysql连接查询匹配所有标签的多个“标签”(多对多关系)?

[英]Mysql join query for multiple “tags” (many-to-many relationship) that matches ALL tags?

I am trying to query for Objects that match ALL of a given set of Tags. 我试图查询匹配给定标签集的所有对象。

Basically I want users to be able to add on more and more Tags to filter or "narrow down" their search results, kind of like newegg.com does. 基本上我希望用户能够添加越来越多的标签来过滤或“缩小”他们的搜索结果,有点像newegg.com。

My table structure is a table of Objects, a table of Tags, and a MANY:MANY relation table ObjectsTags. 我的表结构是一个对象表,一个标签表和一个MANY:MANY关系表ObjectsTags。 So I have a JOIN query like so: 所以我有一个像这样的JOIN查询:

SELECT * FROM Objects
LEFT OUTER JOIN ObjectsTags ON (Objects.id=ObjectsTags.object_id)
LEFT OUTER JOIN Tags ON (Tags.id=ObjectsTags.tag_id)

I tried using an IN clause/condition, like this: 我尝试使用IN子句/条件,如下所示:

SELECT * FROM Objects
LEFT OUTER JOIN ObjectsTags ON (Objects.id=ObjectsTags.object_id)
LEFT OUTER JOIN Tags ON (Tags.id=ObjectsTags.tag_id)
WHERE Tags.name IN ('tag1','tag2')
GROUP BY Objects.id

But I learned that this simulates a series of ORs, so the more tags you add to the query the MORE results you get, instead of the result set narrowing down like I was hoping. 但我了解到这会模拟一系列OR,因此您在查询中添加的标签越多,您获得的结果就越多,而不是像我希望的那样缩小结果集。

I also tried doing multiple LIKE WHERE conditions, ANDed together: 我也试过做多个LIKE WHERE条件,ANDed一起:

SELECT * FROM Objects
LEFT OUTER JOIN ObjectsTags ON (Objects.id=ObjectsTags.object_id)
LEFT OUTER JOIN Tags ON (Tags.id=ObjectsTags.tag_id)
WHERE Tags.name LIKE 'tag1' 
AND Tags.name LIKE 'tag2'
GROUP BY Objects.id

But this returns no results, since when the results are grouped together the OUTER JOINed Tags.name column just contains 'tag1', and not also 'tag2'. 但是这不会返回结果,因为当结果组合在一起时,OUTER JOINed Tags.name列只包含'tag1',而不是'tag2'。 The result row where 'tag2' matched is "hidden" by the GROUPing. 'tag2'匹配的结果行​​由GROUPing“隐藏”。

How can I match ALL of the tags to get the "narrow down" or "drill down" effect that I am after? 如何匹配所有标签以获得我所追求的“缩小”或“向下钻取”效果? Thanks. 谢谢。

Use: 使用:

  SELECT * 
    FROM OBJECTS o
    JOIN OBJECTSTAGS ot ON ot.object_id = o.id
    JOIN TAGS t ON t.id = ot.tag_id
   WHERE t.name IN ('tag1','tag2')
GROUP BY o.id
  HAVING COUNT(DISTINCT t.name) = 2

You were missing the HAVING clause. 你错过了HAVING子句。

There's no need to LEFT JOIN if you want only rows where both tags exist. 如果您只想要存在两个标记的行,则无需LEFT JOIN。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM