0

我有一个表posts和一个表post_tags 这是我的帖子表结构示例:

post_id      int(11)
post_user    int(11)
post_title   text
post_content longtext

这是我的 post_tags 结构示例:

post_id  int(11)
tag_id   int(11)

我需要的是从posts表中选择同时具有tag_id1 和 2 的所有帖子,我尝试了不同的连接但没有成功。

post_tags 表数据示例:

post_id  tag_id
1        1
2        1
5        2
6        1
6        2

例如,在这里我的查询应该返回 post(来自 post 表),其 id 为 6,在示例 post_id 为 6 时,请注意 tag_id 1 和 tag_id 2 不仅有一个,而且同时有两个。

4

4 回答 4

2

您可以通过聚合来做到这一点:

select post_id
from post_tags pt
group by post_id
having sum(tag_id = 1) > 0 and
       sum(tag_id = 2) > 0;

如果您想从 中查看实际信息posts,只需加入该表即可。

编辑(有点解释):

您有一个“set-within-sets”查询。这是一个常见的查询,我更喜欢使用聚合和子句来解决它having,因为这是最通用的方法。

子句中的每个条件都在having计算与其中一个标签匹配的行数。也就是说,sum(tag_id = 1)正在计算符合条件的行数post_tags。条件> 0只是说“tag_id = 1 至少存在一行”。

我喜欢这种方法的原因是你可以很容易地概括它。如果您还想要标签 3 和 4:

having sum(tag_id = 1) > 0 and
       sum(tag_id = 2) > 0 and
       sum(tag_id = 3) > 0 and
       sum(tag_id = 4) > 0;

等等。

于 2013-08-30T19:18:55.463 回答
0
select a.post_id, b.post_id, a.post_user, b.post_tags
from posts as a
inner join post_tags as b
where b.post_tags in(1, 2)

或者

select a.post_id, b.post_id, a.post_user, b.post_tags
from posts as a
inner join post_tags as b
where b.post_tags =1 or b.post_tags = 2
于 2013-08-30T19:31:13.017 回答
0

试试这个:

SELECT post.*
FROM (SELECT T1.post_id
      FROM (SELECT * FROM post_tags WHERE 1 IN(tag_id)) T1
      INNER JOIN (SELECT * FROM post_tags WHERE 2 IN(tag_id)) T2 ON T1.post_id = T2.post_id)
      T3
INNER JOIN post ON T3.post_id=post.post_id;

SQL 小提琴链接:http ://sqlfiddle.com/#!2/04f74/33

于 2013-08-30T19:29:10.350 回答
0

这应该工作

select q.* from (
      select  p.post_id as post_id from post_tags p 
      where p.tag_id=1 
      and exists (
            select 1 from post_tags p2 
            where p2.post_id=p.post_id 
            and p2.tag_id=2)
    ) as t
    inner join  posts q on posts_id=t.post_id;
于 2013-08-30T19:30:28.780 回答