我在Stackoverflow中已经解决了很多关于这个问题的问题,但我认为这是不同的。
我要做的是让用户能够按标签过滤帖子,以便只看到留下过滤的标签。换句话说,如果用户选择标签“tag1”,它会显示带有该标签的帖子,并且还会显示发布共享的其他标签,但会隐藏过滤后没有可见帖子的标签。
我有表帖子, posts_tags 和标签。 Posts_tags有post_id和tag_id。我设法使用特定的tagset获得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;
假设这个查询给出了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行。
编辑:使用场景:
用户搜索更多标签,然后:
我不想提供完整的清单,只提供
一个。那还没有被选中。
湾用于在步骤2中检索的帖子。
编辑:基于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');
答案 0 :(得分:2)
嗯,这是我能在凌晨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)是您正在寻找的标签,当然,计数必须与您用来过滤的标签数量相匹配。
这是example(注意我稍微更改了数据)
答案 1 :(得分:0)
你的意思是扩展为只包含tag4,tag5,tag6 ......为什么不在()中更改你的WHERE t.name以反映那些标签......
或者......你的意思是它必须包括标签1,2,3,还要包括(tag4或tag5或tag6)中的任何一个......
如果是这种情况,我会改变以下的地方......
WHERE t.name IN ('tag1', 'tag2', 'tag3', 'tag4', 'tag5', 'tag6' )
GROUP BY pt.post_id
HAVING sum( if( t.name in ('tag1', 'tag2', 'tag3' ), 1, 0 )) = 3
AND sum( if( t.name in ('tag4', 'tag5', 'tag6' ), 1, 0 )) > 0