如何根据来自另一个表的多个值的组合选择记录?

时间:2017-12-24 09:41:27

标签: sql postgresql

假设我有3张桌子。 studentsarticles之间的关系是多对多student_articles

生:

-----------------------
id      name       ...
-----------------------
1       Alex          
2       Bob         
3       Cathy         
...

文章:

------------------------             
id      title  ...          
------------------------            
1       A                         
2       B                         
3       C                          
...                

student_articles:

-------------------------------------             
id      student_id  article_id  ...          
-------------------------------------         
1       1            1             
2       3            1             
3       1            2   
4       3            2  
...                 

现在我想要由Alex和Cathy编写的SELECT articles(至少应该根据上面的信息选择第1和第2条),我该如何编写SQL查询?在这个例子中,["Alex", "Cathy"]就是我所说的标题中的“多个值的组合”。这种组合是一个变量。因此,理想情况下,即使学生名称列表很大(如包含10个以上的名字),查询也应该是自适应和整洁的。

BTW,我正在使用 PostgreSQL 10.1 。感谢。

2 个答案:

答案 0 :(得分:1)

select 
    z.id    as article_id,
    z.title
from
    students x join student_articles y on x.id = y.student_id
        join articles z on y.article_id = z.id
where
    x.name = 'Alex'
intersect
select 
    z.id    as article_id,
    z.title
from
    students x join student_articles y on x.id = y.student_id
        join articles z on y.article_id = z.id
where
    x.name = 'Cathy'
except
select 
    z.id    as article_id,
    z.title
from
    students x join student_articles y on x.id = y.student_id
        join articles z on y.article_id = z.id
where
    x.name not in ('Alex', 'Cathy');

结果:

 article_id | title 
------------+-------
          2 | B
          1 | A
(2 rows)

这是一个结构合理的多对多关系,因此可以使用标准SQL轻松获得正确的答案。您可能需要查看http://www.thedatastudio.net以获取更多SQL示例。

感谢Turo在我的第一次尝试中指出了这个缺陷。上面的代码现在解决了这个问题。我添加了以下行来测试它:

insert into articles (id, title) values (4, 'D');
insert into student_articles (id, student_id, article_id) values (5, 1, 4);
insert into student_articles (id, student_id, article_id) values (6, 2, 4);
insert into student_articles (id, student_id, article_id) values (7, 3, 4);

这是一个标题" D"亚历克斯写的,凯茜鲍勃。早期版本也包括这个。

答案 1 :(得分:1)

手头没有Postgress这是一个更多的猜测,但是在文件记录之后它可能像是

SELECT * FROM articles 
INNER JOIN student_articles ON student_articles.article_id = articles.id AND  
INNER JOIN students ON student_articles.student_id = students.id 
GROUP BY articles.id
HAVING array_agg(students.name)::text[] @> ARRAY['Alex','Cathy'] AND array_agg(students.name)::text[] <@ ARRAY['Alex','Cathy']