Fiddle: http://sqlfiddle.com/#!9/ea5723/9 Here is my plausible solution, but I think there might be a better answer out there. In this answer, I add multiple joins for every tag that needs to be compared. So if I am looking for 5 tags in common the query will have 10 join statements. SELECT places.id AS p_id, places.name FROM places JOIN place_taxonomy pt1 ON places.id=pt1.place_id JOIN tags t1 ON pt1.tag_id=t1.id AND t1.id=1 JOIN place_taxonomy pt2 ON places.id=pt2.place_id JOIN tags t2 ON pt2.tag_id=t2.id AND t2.id=2 GROUP BY p_id; The above query will give the response of Plan C which has both tags `tag-z` and `tag-y` +------+--------+ | p_id | name | +======+========+ | 3 | Plan C | +------+--------+ **Update:** Alternatively if selecting tags by id and not any other column then we can remove the tags join. At least then we only have one additional join for every relationship checking. SELECT places.id AS p_id, places.name FROM places JOIN place_taxonomy pt1 ON places.id=pt1.place_id AND pt1.tag_id=1 JOIN place_taxonomy pt2 ON places.id=pt2.place_id AND pt2.tag_id=2 GROUP BY p_id;