从连接表中过滤

fin*_*vin 2 mysql sql filtering join

我在执行一个棘手的 SQL 查询时遇到了一些麻烦。

在我的 MySQL 数据库中,有主题表、标签和标签主题来连接它们。我想获取共享相同指定标签的主题。例如,假设我有 3 个标签,id 分别为 1、2 和 3,我想获取与标签 1、2 和 3 关联的所有主题。主题可以具有其他标签,但必须具有所有指定的标签。

请帮我想想 xD

编辑:在这个问题中找到了使用 GROUP BY 的解决方案:仅获取与连接表中的所有条目匹配的行(SQL) 如果有人有更优雅的解决方案,请发布:)

Bil*_*win 5

JOIN解决方案:

SELECT t.*
FROM topics t
 JOIN tags_topics t1 ON (t.id = t1.topicId AND t1.tagId = 1)
 JOIN tags_topics t2 ON (t.id = t2.topicId AND t2.tagId = 2)
 JOIN tags_topics t3 ON (t.id = t3.topicId AND t3.tagId = 3)
Run Code Online (Sandbox Code Playgroud)

GROUP BY解决方案:

请注意,除非您使用 MySQL 或 SQLite,否则您需要列出t.*子句中的所有列GROUP BY

SELECT t.*
FROM topics t JOIN tags_topics tt 
  ON (t.id = tt.topicId AND tt.tagId IN (1,2,3))
GROUP BY t.id, ...
HAVING COUNT(*) = 3;
Run Code Online (Sandbox Code Playgroud)

子查询解决方案:

SELECT t.*
FROM topics t
WHERE t.id = ANY (SELECT topicId FROM tags_topics tt WHERE tt.tagId = 1)
  AND t.id = ANY (SELECT topicId FROM tags_topics tt WHERE tt.tagId = 2)
  AND t.id = ANY (SELECT topicId FROM tags_topics tt WHERE tt.tagId = 3);
Run Code Online (Sandbox Code Playgroud)

修改后的GROUP BY解决方案:

GROUP BY通过隔离子查询中的搜索来简化子句。

SELECT t.*
FROM topics t
WHERE t.id IN (
  SELECT tt.topicId FROM tags_topics tt 
  WHERE tt.tagId IN (1,2,3))
  GROUP BY tt.id HAVING COUNT(*) = 3
);
Run Code Online (Sandbox Code Playgroud)