选择联结表中具有多个值的行
Posted
技术标签:
【中文标题】选择联结表中具有多个值的行【英文标题】:Select rows which has multiple values in junction table 【发布时间】:2018-02-22 17:18:51 【问题描述】:我有三张桌子:
posts (id, content)
posts_tags (posts_id, tags_id)
tags (id, tag)
如何选择所有具有(至少)2 个特定标签的帖子(比如说 id 为 1 和 2 的标签)?
例如帖子表:
id content
---- -------
1 post1
2 post2
3 post3
标签表:
id tag
---- ------
1 tag1
2 tag2
3 tag3
posts_tags 表:
posts_id tags_id
---------- ---------
1 1
1 2
2 1
3 1
3 2
3 3
然后我期待以下结果:
id content
---- ---------
1 post1
3 post3
使用 ID 3 发布(因为它有标签 1、2 和 3)和使用 id 1 发布(因为它有带有 id 1 和 2 的标签)但没有发布 2,因为它没有带有 id 2 的标签.
假设我无法更改表结构。
【问题讨论】:
请Edit您的问题并添加一些sample data 和基于该数据的预期输出。 Formatted text 请no screen shots。 edit 您的问题 - 请不要在 cmets 中提供邮政编码或其他信息。 【参考方案1】:SELECT *
FROM posts p
JOIN posts_tags pt ON pt.posts_id = p.id
WHERE pt.tags_id IN (1,2);
SELECT *
FROM posts p
JOIN posts_tags pt ON pt.posts_id = p.id
WHERE pt.tags_id = 1 OR pt.tags_id = 2;
SELECT *
FROM posts p
JOIN posts_tags pt ON pt.posts_id = p.id
WHERE pt.tags_id = 1 AND pt.tags_id = 2;
编辑:又快又脏
WITH j AS (
SELECT pt.posts_id AS post,
p.content AS content,
STRING_AGG(pt.tags_id::TEXT,',') AS agg
FROM posts p
JOIN posts_tags pt ON pt.posts_id = p.id
GROUP BY pt.posts_id, p.content
)
SELECT post,content
FROM j
WHERE STRING_TO_ARRAY(agg,',') @> ('2,1'::TEXT[])
【讨论】:
我可能不清楚。这也将选择只有一个标签的帖子。 刚刚在我的回答中添加了OR
和 AND
的第二个选项
我认为 OR 在功能上等同于 IN 示例,并且 AND 永远不会返回任何行,因为没有行具有多个标签 ID。
最后一次尝试.. 我刚刚添加了一个使用 CTE 的示例 :-)【参考方案2】:
找到了我自己问题的答案:
SELECT posts.*
FROM posts
INNER JOIN posts_tags ON posts_tags.posts_id = posts.id
INNER JOIN tags ON tags.id = posts_tags.tags_id
WHERE tags.id IN (1, 2)
GROUP BY posts.id
HAVING COUNT(*) > 1
【讨论】:
以上是关于选择联结表中具有多个值的行的主要内容,如果未能解决你的问题,请参考以下文章