提出一个简单的问题,只希望每个人都有乐趣解决它。 我有两张桌子。 1.学生 2.课程
学生
+----+--------+
| id | name |
+----+--------+
| 1 | User1 |
| 2 | User2 |
+----+--------+
场
+----+------------+------------+
| id | student_id | course_name|
+----+------------+------------+
| 1 | 1 | English |
| 2 | 1 | Chinese |
| 3 | 2 | English |
| 4 | 2 | Japanese |
+----+------------+------------+
我希望得到所有学生的结果,他们使用英文和中文,而不是英文或中文。
预期结果:
+----+------------+------------+
| id | student_id | course_name|
+----+------------+------------+
| 1 | 1 | English |
| 2 | 1 | Chinese |
+----+------------+------------+
我们通常做的是
select * from student join course on (student.id = course.student_id) WHERE course_name = 'English' OR course_name = 'Chinese'
但是在这个结果中我可以获得User2记录,这不是我预期的结果。我希望记录只显示用户只选择英语+中文课程。
答案 0 :(得分:3)
两次加入课程:一次是英语,一次是中文。那就是:
select student.*
from student
join course english_course on student.id = english_course.student_id
join course chinese_course on student.id = chinese_course.student_id
where english_course.course_name = 'English'
and chinese_course.course_name = 'Chinese'
甚至
select * from student
where exists (select 1 from course
where course.course_name = 'English' and course.student_id = student.id)
and exists (select 1 from course
where course.course_name = 'Chinese' and course.student_id = student.id);
也将消除课程中的重复(student_id,course_name)条目。
我假设(student_id,course_name)被编入索引以驱动这两个。你的命名有点奇怪:“课程”表没有描述课程,它描述了从学生到课程的关联。我个人称之为“student_course”(或类似的,可能是后缀“_map”或“_link”),并且它包含一个引用带有id和名称的课程表的“course_id”。
(我也更喜欢将主键命名为一致而不是在他们自己的表中将它们称为“id”,但这只是挑剔,而且更加主观)
只是为了好玩:
select student.*
from student
join course on student.id = course.student_id
where course.course_name = 'English'
intersect
select student.*
from student
join course on student.id = course.student_id
where course.course_name = 'Chinese'
现实情况是,使用“intersect”来比较基于相同表格的两个结果集有点傻。
答案 1 :(得分:1)
您可以使用having子句来强制匹配:
select s.student_id
from student s
join course c
on s.id = c.student_id
and c.course_name in ('English', 'Chinese')
group by
s.student_id
having count(distinct c.course_name) = 2
要检索其他列,您可以加入此查询:
select *
from student s
join course c
on s.id = c.student_id
join (
<query from above here>
) filter on s.id = filter.student_id
答案 2 :(得分:0)
您可以使用IN运算符
select * from student join course on (student.id = course.student_id)
WHERE course_name = 'English' and student.id IN
(select student.id from student join course on (student.id = course.student_id)
WHERE course_name = 'Chinese')
答案 3 :(得分:0)
你可能想要自我加入:
SELECT left.student_id sid1, right.student_id sid2,
left.course_name cn1, right.course_name cn2
FROM course left, course right
WHERE sid1 = sid2 AND
cn1 = 'English' AND cn2 = 'Chinese'
将其加入学生表并不困难。