如何找到补充标签?

时间:2009-09-03 16:07:30

标签: sql mysql

我有一个包含3个表的MySQL数据库:

  1. 主要记录表 “曲目”(如音乐)
  2. 标签表 称为“标签”
  3. 两个名为“taggings”的连接表
  4. 标签表基本上是一个预定义的类型列表。然后,一个轨道可以有一个或多个标签(通过连接表)。

    这个想法是,用户检查他或她想要找到曲目的流派(标签)。但我还希望界面能够反映哪些标签不再“有用”,即与当前所选标签互补的标签。

    编辑:我错过的是我需要找到与当前所选标签互补的标签。请参阅下面的评论。

    示例:用户选择“摇滚”和“弹出”标签,并显示与“摇滚”+“弹出”匹配的曲目列表。但是假设数据库中没有匹配“jazz”的曲目。在这种情况下,我想在界面中禁用“jazz”标签,因为“摇滚”+“弹出”+“爵士乐”会给出零结果。

    有没有一种聪明的方法可以用MySQL做到这一点?

4 个答案:

答案 0 :(得分:1)

select 
   tagid 
from 
   taggings 
where 
   trackid in ([list of, or subquery for your selected tracks])

禁用所有标记,除非结果包含其ID。或者禁用所有标记,然后重新启用此查询返回的标记。您也可以进行一些重组并将其转换为“不在”查询,但这通常会更慢。

答案 1 :(得分:0)

这可能不是最有效的:

SELECT 
    TagId --to disable
FROM Tags 
WHERE TagId NOT IN(
    SELECT Distinct TagId FROM Taggings WHERE TrackId IN (
        SELECT TrackId FROM Taggings WHERE TagId in (1, 2)
    ) 
)
  
      
  1. 获取与当前所选标签匹配的所有曲目。
  2.   
  3. 将分配给这些曲目的所有标签
  4.   
  5. 禁用不在此列表中的标签
  6.   

修改
那怎么样:

SELECT 
    DISTINCT TagId 
FROM 
    Taggings
GROUP BY 
    TagId,
    TrackId HAVING TrackId IN (
        SELECT 
            TrackId
        FROM 
            Taggings
        WHERE
         TagId in ( 1, 2)
    )

这应该返回应该启用的所有标记。

答案 2 :(得分:0)

您是否可以控制标签添加到曲目的方式?如果您可以加入,可以创建一些额外的元数据。

基本上是标签之间的多对多连接。每次添加标记时,都会为此连接表添加一条记录,其中包含旧标记/新标记对(较低的id作为减少重复的第一个值),用于该轨道上的每个旧标记。 IIRC,有一种方法可以设置表来忽略重复插入,而不是抛出错误。在删除标签期间,您还必须管理此表,这将更耗时,但这可能是一种罕见的事件。

有了上述内容,您就可以通过简单的查询来识别仍然相关的标记:

select 
   tag_a
from
   related_tags
where
   tag_b in ([tags_already_in_search])
union
select
   tag_b
from
   related_tags
where
   tag_a in([tags_already_in_search])

此解决方案实质上将一些处理时间转移到添加和删除标记的时间点。

答案 3 :(得分:0)

结束这样做:

  • 标记曲目时,其标记ID将按顺序连接并添加到1列查找表(当然也包括标记)。例如。 “1,2,4,6,9,”被添加到查找中(导致/尾随逗号的原因)
  • 在搜索时选择标记时,它们会被类似地连接起来,并在LIKE子句中使用,该子句从查找表中选择包含这些标记ID的所有连接
  • 然后处理找到的连接以获取它们包含的所有ID
  • 结果列表中没有哪个ID因此是对所选ID的补充