sql select具有确切的结果

时间:2010-05-29 12:35:48

标签: sql mysql

提出一个简单的问题,只希望每个人都有乐趣解决它。 我有两张桌子。 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记录,这不是我预期的结果。我希望记录只显示用户只选择英语+中文课程。

4 个答案:

答案 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'

将其加入学生表并不困难。