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

Sql 如何根据来自另一个表的多个值的组合选择记录?,sql,postgresql,Sql,Postgresql,假设我有三张桌子。学生和文章之间的关系是多对多通过学生文章 学生: ----------------------- id name ... ----------------------- 1 Alex 2 Bob 3 Cathy ... 文章: ------------------------ id title ... --

假设我有三张桌子。
学生
文章
之间的关系是多对多通过
学生文章

学生:

-----------------------
id      name       ...
-----------------------
1       Alex          
2       Bob         
3       Cathy         
...
文章:

------------------------             
id      title  ...          
------------------------            
1       A                         
2       B                         
3       C                          
...                
学生文章:

-------------------------------------             
id      student_id  article_id  ...          
-------------------------------------         
1       1            1             
2       3            1             
3       1            2   
4       3            2  
...                 
现在,我想选择由Alex和Cathy编写的
文章
(根据上述信息,至少应该选择第1和第2条),我应该如何编写SQL查询?在这个例子中,
[“Alex”,“Cathy”]
就是我在标题中所说的“多个值的组合”。这个组合是一个变量。因此,理想的情况是,即使学生姓名列表很大(比如包含10个以上的姓名),查询也应该是自适应的、整洁的

顺便说一句,我正在使用PostgreSQL 10.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很容易获得正确答案。您可能需要查看更多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”。早期版本也会包括这一点。

手边没有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']
从文章中选择*
在学生文章上内部加入学生文章。文章id=文章。id和
内部加入学生文章。学生id=学生id
按项目分组。id

有array_agg(students.name)::text[]@>array['Alex'、'Cathy']和array_agg(students.name)::text[]你错过了“Alex和Cathy的确切写法”部分,我应该排除还有另一位作者以及Alex和Cathy的情况。好的,谢谢你。实际上,
array\u agg
就是我要找的。但你帮我找到了。如果你不介意的话,我会对你的答案做一些修改,然后接受它。谢谢你改进它,让我学习更多关于Postgress的知识,只是为了让那些有同样问题的人明白。同时使用“@>和”