小编典典

mysql多对多关系查询。如何获取已过滤帖子的所有标签?

sql

我正在尝试做的是赋予用户按标签过滤帖子的功能,这样一来,用户
只能看到剩下的要过滤的标签。换句话说,如果用户选择
标签“ tag1”,它将显示具有该标签的帖子,并显示其他帖子,这些帖子
共享但隐藏过滤后没有可见帖子的标签。

我有table的帖子,posts_tags和标签。Posts_tags具有post_id
tag_id。我已经设法使post_ids与特定的标签集一起使用:

SELECT pt.post_id
FROM posts_tags pt
    INNER JOIN tags t
        ON pt.tag_id = t.id
WHERE t.name IN ('tag1', 'tag2', 'tag3')
GROUP BY pt.post_id
HAVING COUNT(DISTINCT t.id) = 3;

Let’s say this query gives post_ids 1, 2, 3:

post 1 has tag1, tag2, tag3 and tag4
post 2 has tag1, tag2, tag3 and tag5
post 3 has tag1, tag2, tag3 and tag6

现在,我的问题是如何扩展查询以仅向用户返回tag4,tag5和 tag6,因为这些标记仍可用于
进一步过滤帖子。如何实现呢?

注意性能也很好。我有130000个帖子,6500个标签,桥表有240000行。

编辑:使用方案:

  1. 用户使用自动完成功能标记标签,并选择多个标签。
  2. 用户根据提交的标签检索帖子。
  3. 用户搜索更多标签,此时:
    我不想给出完整的清单,而只给出那些

一种。尚未选择。

编辑:基于Mosty Mostacho的答案的最终查询:

SELECT DISTINCT pt2.tag_id, t2.name FROM    
(SELECT pt1.post_id
    FROM posts_tags pt1
    INNER JOIN tags t1
        ON pt1.tag_id = t1.id
    WHERE t1.name in ('tag1','tag2','tag3')
    GROUP BY pt1.post_id
    HAVING COUNT(DISTINCT t1.id) = 3) MatchingPosts
INNER JOIN posts_tags pt2 ON (MatchingPosts.post_id = pt2.post_id)
INNER JOIN tags t2 ON (pt2.tag_id = t2.id)
WHERE t2.name NOT IN ('tag1','tag2','tag3');

阅读 178

收藏
2021-03-23

共1个答案

小编典典

好吧,这是我在凌晨4:30想到的最好的方法:

SELECT distinct tag_id FROM
    (SELECT pt1.post_id FROM pt1
    INNER JOIN tags t1 ON (pt1.tag_id = t1.id)
    WHERE t1.id IN (1, 2)
    GROUP BY pt1.post_id
    HAVING COUNT(DISTINCT t1.id) = 2) MatchingPosts
INNER JOIN pt2 ON (MatchingPosts.post_id = pt2.post_id)
WHERE (pt2.tag_id NOT IN (1, 2))

(1,2)是您要寻找的标签,计数当然必须与您要用来过滤的标签数量相匹配。

2021-03-23