найти все наборы, содержащие один определенный тег (с учетом значения):
select tags_sets_id
from tags_has_sets, tags
where value = 'foo'
and tags_id = id;
найти все наборы, содержащие один из двух (или более) определенных тегов (с учетом значений):
select distinct tags_sets_id
from tags_has_sets, tags
where value in ('foo', 'bar')
and tags_id = id;
найти все наборы, содержащие оба точно двух конкретных тега:
select t1.tags_sets_id
from tags_has_sets t1, tags tags1,
tags_has_sets t2, tags tags2
where tags1.value = 'foo'
and tags2.value = 'bar'
and t1.tags_id = tags1.id
and t2.tags_id = tags2.id
and t1.tags_sets_id = t2.tags_sets_id;
обратите внимание, что последнее решение не обобщает, но вы могли бы создать обобщенный алгоритм для генерации n-объединенного оператора SQL на лету.
вот последняя реализация, которую обобщает , хотя я не знаю ее характеристики производительности по сравнению с методом генерируемого соединения (спасибо @ypercube за отличное улучшение моего первоначального предложения):
select tags_sets_id
from tags_has_sets, tags
where value in ('foo', 'bar', 'baz')
and id = tags_id
group by tags_sets_id
having count(*) = 3;
-- formerly: having group_concat(distinct value order by value)
-- ='bar,baz,foo';