根据多个标准查找相关文章

时间:2012-11-07 15:51:49

标签: mysql sql

这个问题与this one类似,但有所不同:我有八种不同类型的标签。

这样的事情:

videos      [id, title]
tags1       [id, tag]
tags2       [id, tag]
tags3       [id, tag]
tags4       [id, tag]
tags5       [id, tag]
tags6       [id, tag]
tags7       [id, tag]
tags8       [id, tag]
video_tags1 [vid_id, tag_id]
video_tags2 [vid_id, tag_id]
video_tags3 [vid_id, tag_id]
video_tags4 [vid_id, tag_id]
video_tags5 [vid_id, tag_id]
video_tags6 [vid_id, tag_id]
video_tags7 [vid_id, tag_id]
video_tags8 [vid_id, tag_id]

鉴于单个video.id,我想根据哪些视频共享最多的相关视频。我发现很难找到一种方法来做到这一点,更不用说一种不会让服务器瘫痪的方法。

2 个答案:

答案 0 :(得分:2)

如果您可以更改数据库模型,那么这些提案可能适合您。

以这种方式重新定义表格:

videos      [id, title]
tags    [id, tag_type,tag]
videos_tags [vid_id, tag_id]

你也可以添加一个tag_type表(它有8行,每个yourtag类型一个),以提高一致性。

然后这个查询(它可能有一些语法错误,但我的意图是你明白了)会给你视频ID和匹配标签的数量与提供的:

select 
       videos.id, count(videos.id) as nEqualTags 
from 
       videos videos inner join  video_tags vtags on  (vtags.vid_id=videos.id )
where 
       vtags.tag_id in (select tag_id from videos_tags where vt.id = ?) 
group by 
       videos.id 
order by 
       nEqualTags desc

如果nEqualTags低于特定值,您可以添加更多逻辑以减少结果。

(并且还考虑添加一些索引以获得更好的性能)。

希望有所帮助

答案 1 :(得分:1)

我认为在规范化表上工作总是一个好主意,在这种情况下,这个UNION查询可以提供帮助:

(select 1 as tab, vid_id, tag_id from video_tags1
 union select 2 as tab, vid_id, tag_id from video_tags2
 union select 3 as tab, vid_id, tag_id from video_tags3
 ...)

现在你必须使用这样的查询:

SELECT
  tags_1.vid_id, count(*) as common_tags
FROM
  (big union above) video_tags
  INNER JOIN
  (big union above) video_tags_1
  ON video_tags.tab = video_tags_1.tab
  AND video_tags.tags_id = video_tags_1.tags_id
  AND video_tags.vid_id = 1
  AND video_tags_1.vid_id <> 1
GROUP BY video_tags_1.vid_id
ORDER BY common_tags DESC

这将按照它们共有的标签数量返回所有按DESC订购的记录。这可能是如何进行的想法。您应该再添加一个JOIN以获取视频的标题。 如果你还需要获得它们共有的标签的描述......那么它是可能的,但我认为它会使查询复杂化很多!

您确定无法更改数据库模型,只使用表格标记和视频标记吗?它会让事情变得容易多了!