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的知识,只是为了让那些有同样问题的人明白。同时使用“@>和”