Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

My table structure is a table of Objects, a table of Tags, and a MANY:MANY relation table ObjectsTags. So I have a JOIN query like so:

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:

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.

I also tried doing multiple LIKE WHERE conditions, ANDed together:

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'. The result row where 'tag2' matched is "hidden" by the GROUPing.

How can I match ALL of the tags to get the "narrow down" or "drill down" effect that I am after? Thanks.

like image 769
thaddeusmt Avatar asked Jul 16 '10 17:07

thaddeusmt


People also ask

How do I join 4 tables in SQL?

Here first, we will create the database using SQL query as follows. Now, we will use the database using SQL query as follows. Create a table 1, name as s_marks using SQL query as follows. Create a table2 for the professor details as p_details using SQL query as follows.

How do I join one to many tables in SQL?

SQL Join Statement How the two tables should be joined is written in the ON statement. In this case the two tables are joined using the relationship table1.id = table2.id . It is possible to use multiple join statements together to join more than one table at the same time.


1 Answers

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.

There's no need to LEFT JOIN if you want only rows where both tags exist.

like image 88
OMG Ponies Avatar answered Oct 23 '22 17:10

OMG Ponies