选择联结表中具有多个值的行

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 textno screen shotsedit 您的问题 - 请不要在 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[])

【讨论】:

我可能不清楚。这也将选择只有一个标签的帖子。 刚刚在我的回答中添加了 ORAND 的第二个选项 我认为 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

【讨论】:

以上是关于选择联结表中具有多个值的行的主要内容,如果未能解决你的问题,请参考以下文章

选择可能具有相同值的行的多个实例

比较多个表中的值的 SELECT 语句未返回正确的行

按列分组并选择具有多个最小值的行中的所有字段

MYSQL - 将具有多个重复值的行组合起来,然后删除重复项

联结表

查找一列中具有相同值而另一列中具有其他值的行?