Mysql:在表1中找到1行,该行将表2中的多行与给定值连接起来

标签 mysql join

抱歉问题标题..我不知道如何以更清晰的方式写下来。

所以,我有三张 table :

  1. tracks,包含id(轨道ID)和name(轨道名称)
  2. tags,包含id(标签ID)和name(标签名称)
  3. track_tags,包含track_idtag_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/

相关文章:

mysql - inner self join的呈现顺序

mysql - 如何从表中选择并在 MySQL 中使用 LIST RIGHT JOIN

php - 表情符号无法以 HTML 形式工作

mysql - 在 Entity Framework 6 中左联接

mysql - 内连接仅返回 1 行

MySQL - 左连接顺序被忽略

sql - MySQL: "The SELECT would examine more than MAX_JOIN_SIZE rows"

php - 两台MySQL服务器

mysql - PDO 事务提交而不是回滚

php - MySQL 到 PHP 双引号问题