MySQL:如何选择具有某些值的组?
题
说有这样的桌子:
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和3的S tag_id
S,所以在此示例中只是 1
. 。我想到了类似SELECT post_id FROM tags GROUP BY post_id HAVING ...
在我想列出之后 tag_id
该组中存在的s。我怎么做?
解决方案
如果没有任何独特的约束,请尝试:
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;
其他提示
您可以尝试自我加入(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
我已经对您的其他表做出了一些假设。 (即您有一个我打电话给的帖子的表格 posts
一个以tag_id为我称之为的PK tag_table
为了避免使用帖子/标签表的nameclash,我可以看到您已经打电话 tags
)
您需要在列表{1,3}中不存在标签的帖子,其中不存在与相应的post_id/tag_id的匹配记录,因此您可以使用以下构造的构造。
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)
)
另一种替代方法是使用组和计数。 对此问题的方法进行了审查.
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
怎么样
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)
);
@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
不隶属于 StackOverflow