Mysql:如何选择具有特定值的组?

时间:2010-06-21 09:24:25

标签: sql mysql group-by having

说有这样的表:

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)

字段名称非常明显。我想选择同时包含1和3 post_id s的tag_id,因此在此示例中,它仅为1。我想到了类似的东西 SELECT post_id FROM tags GROUP BY post_id HAVING ...在我想列出此群组中的tag_id之后。我该怎么做?

6 个答案:

答案 0 :(得分:6)

如果post_id和tag_id都有唯一约束,那么它也应该有效:

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

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

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

答案 1 :(得分:2)

您可以尝试自我加入(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

答案 2 :(得分:1)

我对你的其他表做了一些假设。 (即你有一个我称为posts的帖子的表和一个我用tag_table作为PK的标签的表来避免使用帖子/标签表的名字标记,我已经可以看到你了致电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。 A review of approaches to this problem is here

答案 3 :(得分:1)

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

答案 4 :(得分: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)
  );

答案 5 :(得分:0)

@ Keeper解决方案的版本

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