9

假设有这样的表:

mysql> SELECT * FROM tags;
+---------+--------+
| post_id | tag_id |
+---------+--------+
|       1 |      2 |
|       1 |      3 |
|       1 |      1 |
|       2 |      1 |
|       2 |      2 |
+---------+--------+
5 rows in set (0.00 sec)

字段名称是不言自明的。我想选择post_id同时具有 1 和 3tag_id的 s,所以在这个例子中它只是1. 我想到了类似 SELECT post_id FROM tags GROUP BY post_id HAVING ...After have I'd like to list tag_ids that are present in this group。我怎么做?

4

6 回答 6

14

如果没有任何唯一约束,请尝试:

SELECT post_id 
FROM tags 
WHERE tag_id = 1 OR tag_id = 3 
GROUP BY post_id 
HAVING count(DISTINCT tag_id) = 2;

或者使用这个HAVING子句,如果试图只检测两个tag_id值:

HAVING MIN(tag_id) <> MAX(tag_id)

如果 post_id 和 tag_id 都具有唯一约束,这也应该有效:

SELECT post_id 
FROM tags 
WHERE tag_id = 1 OR tag_id = 3 
GROUP BY post_id 
HAVING count(*) = 2;
于 2010-06-21T09:47:03.527 回答
3

您可以尝试自加入(N tag_id -> N 加入),但可能速度不快

SELECT t1.post_id 
FROM tags t1 INNER JOIN tags t2 ON t1.post_id = t2.post_id 
WHERE t1.tag_id = 1 AND t2.tag_id = 3
于 2010-06-21T09:34:49.220 回答
2
SELECT post_id
  FROM ( SELECT post_id,
                count(tag_id) AS counter
           FROM tags
          WHERE tag_id IN (1,3)
          GROUP BY post_id
       )
 WHERE counter = 2

将 GROUP_CONCAT() 用于问题的第二部分

SELECT post_id,
       GROUP_CONCAT(tag_id ORDER BY tag_id ASC SEPARATOR ',')
  FROM tags
于 2010-06-21T09:44:29.010 回答
1

我对你的其他表做了一些假设。(即你有一个我已经调用的帖子的表posts和一个以 tag_id 作为 PK 的表,我已经调用了它tag_table以避免与我可以看到你已经调用的帖子/标签表发生名称冲突tags

您想要列表 {1,3} 中不存在标签的帖子,其中不存在与相应的 post_id/tag_id 匹配的记录,因此您可以使用如下所示的双重 NOT EXISTS 构造。

SELECT post_id
FROM posts p
WHERE NOT EXISTS 
    (SELECT * FROM tag_table tt
    WHERE tag_id IN (1,3)
    AND NOT EXISTS
        (SELECT * FROM tags t
        WHERE t.tag_id = tt.tag_id  and
        p.post_id = t.post_id)        
    )

另一种替代方法是使用 Group By 和 Count。此处对解决此问题的方法进行了回顾

于 2010-06-21T09:32:06.237 回答
0

怎么样

SELECT * 
FROM tags 
WHERE post_id in 
  (SELECT post_id AS pid 
   FROM tags 
   WHERE 1 IN (SELECT tag_id FROM tags WHERE post_id = pid) 
   AND 3 IN (SELECT tag_id FROM tags WHERE post_id = pid)
  );
于 2010-06-21T09:34:57.830 回答
0

@Keeper 解决方案的 WHERE 版本

SELECT DISTINCT t1.post_id 
FROM tags t1, tags t2
WHERE 
  t1.post_id = t2.post_id  AND 
  t1.tag_id = 1 AND t2.tag_id = 3
于 2010-06-21T09:41:41.783 回答