[英]sql select with exact outcome
问一个简单的问题,只是希望每个人都乐于解决它。 我有2张桌子。 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记录,这不是我的预期结果。 我只希望记录显示用户仅接受英语+中文课程。
只需两次参加课程:一次是英语,一次是中文。 那是:
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”),并使其包含一个“ course_id”,该ID引用带有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'
现实情况是,使用“相交”比较基于相同表的两个结果集有点愚蠢。
您可以使用hading子句强制匹配:
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
您可以使用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')
您可能想要进行自我加入:
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'
将其连接到学生桌应该不难。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.