繁体   English   中英

SQL选择与确切的结果

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM