Select 行在联结 table 中有多个值
Select rows which has multiple values in junction table
我有三个table:
posts (id, content)
posts_tags (posts_id, tags_id)
tags (id, tag)
我如何 select 所有 post 具有(至少)2 个特定标签(比如说 ID 为 1 和 2 的标签)?
例如,posts table:
id content
---- -------
1 post1
2 post2
3 post3
标签table:
id tag
---- ------
1 tag1
2 tag2
3 tag3
posts_tags table:
posts_id tags_id
---------- ---------
1 1
1 2
2 1
3 1
3 2
3 3
然后我期望得到以下结果:
id content
---- ---------
1 post1
3 post3
Post ID 3(因为它有标签 1、2 和 3)和 post ID 1(因为它有标签 ID 1 和 2)但不是 post 2 因为它没有 ID 为 2 的标签。
假设我无法更改 table 结构。
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[])
找到了我自己的问题的答案:
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
我有三个table:
posts (id, content)
posts_tags (posts_id, tags_id)
tags (id, tag)
我如何 select 所有 post 具有(至少)2 个特定标签(比如说 ID 为 1 和 2 的标签)?
例如,posts table:
id content
---- -------
1 post1
2 post2
3 post3
标签table:
id tag
---- ------
1 tag1
2 tag2
3 tag3
posts_tags table:
posts_id tags_id
---------- ---------
1 1
1 2
2 1
3 1
3 2
3 3
然后我期望得到以下结果:
id content
---- ---------
1 post1
3 post3
Post ID 3(因为它有标签 1、2 和 3)和 post ID 1(因为它有标签 ID 1 和 2)但不是 post 2 因为它没有 ID 为 2 的标签。
假设我无法更改 table 结构。
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[])
找到了我自己的问题的答案:
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