我需要存储一组应用于对象的“标记”。我想用一些类似的东西:
但是为了实现gmail的“隐式社交图”算法(see this question),我需要能够搜索包含一个或多个特定标记的标记组。
所以我想我的问题是,在mysql中,如何以最有效的方式获得两组项的交集?

最佳答案

查找包含一个特定标记(给定值)的所有集:

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';

关于mysql - 如何以最有效的方式获得两组项目的交集?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9308053/

10-13 08:47