抱歉问题标题..我不知道如何以更清晰的方式写下来。
所以,我有三张 table :
tracks
,包含id
(轨道ID)和name
(轨道名称)tags
,包含id
(标签ID)和name
(标签名称)track_tags
,包含track_id
和tag_id
我必须找到列表中指定的具有所有标签的所有轨道(例如,我需要同时查找具有“摇滚”、“流行”和“舞蹈”标签的所有轨道)。
之前,我已经解决了类似的问题,但找到了至少有 1 个标签匹配的所有轨道。这很简单:
SELECT tracks.*
FROM tags
INNER JOIN track_tags ON tags.id = track_tags.tag_id
INNER JOIN tracks ON track_tags.track_id = tracks.id
WHERE tags.name IN('pop', 'rock', 'dance')
GROUP BY tracks.id
但我完全不知道如何找到与列表中的所有标签完全匹配的所有轨道。
我想过检索所有轨道及其所有标签到我的应用程序并在那里过滤轨道 - 但它们的数量相当多(数十万),应用程序也使用分页,可以使用上部的 LIMIT 轻松实现查询。
也许可以用另一种方式来完成,使用 mysql 功能?我真的很害怕选择带有所有标签的所有轨道并在应用程序端过滤它们会杀死网络服务器。
最佳答案
解决此问题的最通用方法是使用带有 having
子句的聚合:
SELECT tracks.*
FROM tags INNER JOIN
track_tags
ON tags.id = track_tags.tag_id INNER JOIN
tracks
ON track_tags.track_id = tracks.id
GROUP BY tracks.id
HAVING sum(tags.name = 'pop') > 0 and
sum(tags.name = 'rock') > 0 and
sum(tags.name = 'dance') > 0;
对此的一个细微变化是在 where 中进行过滤,然后查找三个不同的标签:
SELECT tracks.*
FROM tags INNER JOIN
track_tags
ON tags.id = track_tags.tag_id INNER JOIN
tracks
ON track_tags.track_id = tracks.id
WHERE tags.name IN('pop', 'rock', 'dance')
GROUP BY tracks.id
HAVING count(distinct tags.name) = 3;
关于Mysql:在表1中找到1行,该行将表2中的多行与给定值连接起来,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21069610/