我有一个包含3个表的MySQL数据库:
标签表基本上是一个预定义的类型列表。然后,一个轨道可以有一个或多个标签(通过连接表)。
这个想法是,用户检查他或她想要找到曲目的流派(标签)。但我还希望界面能够反映哪些标签不再“有用”,即与当前所选标签互补的标签。
编辑:我错过的是我需要找到与当前所选集标签互补的标签。请参阅下面的评论。
示例:用户选择“摇滚”和“弹出”标签,并显示与“摇滚”+“弹出”匹配的曲目列表。但是假设数据库中没有也匹配“jazz”的曲目。在这种情况下,我想在界面中禁用“jazz”标签,因为“摇滚”+“弹出”+“爵士乐”会给出零结果。
有没有一种聪明的方法可以用MySQL做到这一点?
答案 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)
)
)
- 获取与当前所选标签匹配的所有曲目。
- 将分配给这些曲目的所有标签
- 禁用不在此列表中的标签
醇>
修改
那怎么样:
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)
结束这样做: