如何在多对多的查询中聚合结果

时间:2015-12-23 09:54:38

标签: mysql subquery

我的数据库中有3个表:

学生

  • id
  • 名称

Student_Course

  • student_id
  • COURSE_ID

课程

  • id
  • 等级

我想列出所有学生以及他们是否已通过所选课程的结果。假设等级< ='C'通过。

我尝试过sql:

SELECT s.*,
IF('C'>=ALL(SELECT c.grade FROM from Course c WHERE c.id=sc.course_id),1,0) as isPass 
FROM Student s LEFT JOIN Student_Course sc on sc.student_id=s.id 

这个sql有效,但如果现在我想要一个列'is​​Good',这意味着所有等级='A',我是否需要再次执行子查询?如何通过仅执行一次子查询来获得'isGood'和'isPass'?

1 个答案:

答案 0 :(得分:2)

我相信在联络表中会更好地提供等级。使用它,我创建了一个可以帮助您解决问题的场景:

<强>方案

create table student (id int, fullname varchar(50));
insert into student values (1, 'john'), (2, 'mary'), (3, 'matt'), (4, 'donald');

create table course (id int, coursename varchar(50));
insert into course values (1, 'math'), (2, 'science'), (3, 'business');

create table student_course (student_id int, course_id int, grade char(1));
insert into student_course values
(1, 1, 'C'), (1, 2, 'C'), (1, 3, 'C'),
(2, 1, 'A'), (2, 2, 'A'), (2, 3, 'A'),
(3, 1, 'A'), (3, 2, 'C'), (3, 3, 'C'),
(4, 1, 'A'), (4, 2, 'C'), (4, 3, 'F');

<强>查询

select s.*, case when all_a_grades.student_id is not null then 'GOOD' else 'MEH' end as grades

from student s 

left join (
    -- find students who got A in all classes
    select student_id, count(distinct ca.id) as aclasses, count(distinct sc.course_id) as allclasses
    from student_course sc
    left join (select id, 'A' as agrade from course) ca 
      on ca.id = sc.course_id and ca.agrade = sc.grade
    group by student_id
    having aclasses = allclasses
) all_a_grades on all_a_grades.student_id = s.id

where not exists (
    -- let's make sure we filter OUT students who have failed
    -- at least one course
    select 1 
    from (
        -- find students who have failed at least one course
        select distinct student_id
        from student_course
        where grade not in ('A', 'B', 'C')
    ) t where t.student_id = s.id
)

<强>结果

| id | fullname | grades | 
| 1  | john     | MEH    | 
| 2  | mary     | GOOD   | 
| 3  | matt     | MEH    |