MYSQL如何确保存在多个关联

时间:2012-03-20 07:47:54

标签: mysql ruby-on-rails

所以, 我想要一个SQL查询,我可以在其中强制执行具有多个关联的对象 所以我想查询他们拥有我限制的所有标签的所有视频

因此视频必须有一个videos_tags,将其与tags.id 1,2和3

相关联

到目前为止我试过

SELECT videos.*, tags_videos.tag_id, tags_videos.video_id FROM videos
LEFT JOIN tags_videos ON tags_videos.video_id = videos.id
WHERE tags_videos.tag_id IN (1,2,3)

但这似乎更像是OR子句,而不是AND子句和Exclusive和IN语句?

这也是Rails中有活动记录的。有没有办法通过Rails中的AR轻松完成这项工作?

继承人我尝试过的事情

Video.all.select{|v| params[:tags].select{|t| v.tag_ids.include?(t.to_i)}.count == params[:tags].count }

1 个答案:

答案 0 :(得分:1)

如果您想要包含标签1,2和3的视频,请设想结果行需要的样子。你会发现每个标签都需要一列。要执行此操作,您需要针对要匹配的每个标记加入一次tags_videos。

SELECT videos.* FROM videos
INNER JOIN tags_videos t1 ON (t1.video_id = videos.id AND t1.tag_id=1)
INNER JOIN tags_videos t2 ON (t2.video_id = videos.id AND t2.tag_id=2)
INNER JOIN tags_videos t3 ON (t3.video_id = videos.id AND t3.tag_id=3)

我还使用了INNER JOIN而不是LEFT JOIN,因为你对任何不匹配的东西都不感兴趣。

从概念上讲,您可以将此查询视为首先获取所有标记为1的视频,然后查看哪些视频还包含标记2.现在我们有了标记为1 + 2的视频,我们可以看到那些也有tag3。您可以根据需要继续使用尽可能多的标签。

虽然我怀疑它适用于您的情况,但一种替代方法是使用SET列类型来存储视频的所有标记,但这只允许64个不同的标记。优点是该列可以存储在视频表中,因此不需要连接(您只需多次使用FIND_IN_SET的WHERE子句)