假设我有3张桌子。 students
和articles
之间的关系是多对多到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 。感谢。
答案 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']