查询结果不是我想要的

时间:2013-07-07 19:04:15

标签: mysql sql left-join

我正在运行此查询:

    select distinct(course.course) as course, count(students.studentid) as adm1,
    count(cclogs.newstudentid) from course
    left join students on (course.c_id=students.course and students.doa='2013-07-06')
    left join cclogs on (cclogs.newcid=course.c_id and doc='2013-07-06' and
    students.studentid=cclogs.newstudentid)
    where course.exampattern='2' 
    group by course.c_id

现在我有三个表,学生,课程和CClog。

我想要的是,课程表中的所有课程,学生表中的学生以及cclogs。但是当我使用这个students.studentid = cclogs.newstudent时,没有结果为coloum计数(cclogs.newstudent)。有什么想法吗?

表格是这样的:

C_id   |   Name
 1         Abc
 2         Bcd

学生

Studentid  |   DOA         |   course
   1a        2013-07-05         Abc
   2a        2013-07-05         Bcd
   3a        2013-07-05         Bcd
   4a        2013-07-06         Abc
   5a        2013-07-05         Bcd
   6a        2013-07-06         Abc

CClogs

   id     |    newstudentid     |   oldstudentid   |   DOC      |  newcourse
    1              1b                   1a           2013-07-06      Bcd   
    2              5b                   5a           2013-07-06      Abc

现在当我运行查询时,假设我想要2013-07-06的结果那么结果应该是这样的:

 Course     |     adm1      |       newstudentid
  Abc              2                      1
  Bcd              1                      1

1 个答案:

答案 0 :(得分:0)

我已经重写了一下你的查询,试图通过对表进行别名,并将应用于连接表(学生和cclogs)的过滤逻辑移出from子句并进入,使其更清晰,更容易理解子查询:

select c.course, count(s.studentid) as adm1, count(l.newstudentid) as countNew
from course c
  left join (select * from students where doa = '2013-07-06') s on c.c_id = s.course 
  left join (select * from cclogs where doc = '2013-07-06') l 
    on c.c_id = l.newcid and s.studentid = l.newstudentid
where c.exampattern='2' 
group by c.c_id

现在看看我在这里得到的东西,并将它与您的数据和要求进行比较,根据您给出的样本数据,我认为在您的查询运行时发生的事情是:

课程和学生之间的联接按预期发生,因为基表(课程)中有行,学生中的行可以与课程相关联。但是,当加入ccLogs时,学生中没有newStudentID存在的行(样本数据中的所有newStudentID都是Bs,而Students中的所有StudentID都是As),因此左边连接的ccLogs只生成空值;

当select子句执行时,它会失败第三列,因为对于所有输出行(即课程表中的每一行),ccLogs表不返回任何内容,并且查询需要计数null。

我认为问题可以解决如下:

select c.course, count(s.studentid) as adm1, 
  sum(case when l.newstudentid is null then 0 else 1 end) as countNew
from course c
  left join (select * from students where doa = '2013-07-06') s on c.c_id = s.course 
  left join (select * from cclogs where doc = '2013-07-06') l 
    on c.c_id = l.newcid and s.studentid = l.newstudentid
where c.exampattern='2' 
group by c.c_id

试一试,看看它是否有效。

希望这有帮助