mysql查询不一致

时间:2011-11-21 02:35:12

标签: mysql sql

以下查询给出了不同行的不同结果,它应该在所有行上给出相同的结果。

以下是查询:

select * from 
    (SELECT mjla_db.StudentRecordTable2.studentId, 
            mjla_db.StudentTable2.lastName as `Last Name`, 
            mjla_db.StudentTable2.firstName as `First Name`, 
            sum(if(quizId=60,quizGrade,0)) as `Quiz 60`, 
            sum(if(quizId=64,quizGrade,0)) as `Quiz 64`, 
            sum(if(quizId=71,quizGrade,0)) as `Quiz 71`,
            (sum(quizGrade*(1-abs(sign(quizId-60)))) + 
                sum(quizGrade*(1-abs(sign(quizId-64)))) + 
                sum(quizGrade*(1-abs(sign(quizId-71)))) )/3 
                as Averages 
    FROM mjla_db.StudentRecordTable2, mjla_db.StudentTable2 
    where (mjla_db.StudentRecordTable2.studentId=mjla_db.StudentTable2.studentId) 
    GROUP BY studentId) as A 
where A.studentId 
in (select mjla_db.ClassStudentTable2.studentId 
    from mjla_db.ClassStudentTable2 
    where mjla_db.ClassStudentTable2.classId='CS3071F2011');

测验数量是动态的,学生数量是动态的。


以下是mjla_db.StudentRecordTable2.classId='CS3071F2011'

表格的内容
+-------------+-----------+-----------+--------+
| classId     | studentId | quizGrade | quizId |
+-------------+-----------+-----------+--------+
| CS3071F2011 | A1        |      NULL |     60 |
| CS3071F2011 | A2        |      NULL |     60 |
| CS3071F2011 | A5        |      NULL |     60 |
| CS3071F2011 | A1        |      NULL |     64 |
| CS3071F2011 | A2        |      NULL |     64 |
| CS3071F2011 | A5        |      NULL |     64 |
| CS3071F2011 | A7        |      NULL |     64 |
| CS3071F2011 | A3        |      NULL |     64 |
| CS3071F2011 | A4        |      NULL |     64 |
| CS3071F2011 | A3        |      NULL |     60 |
| CS3071F2011 | A4        |      NULL |     60 |
| CS3071F2011 | A7        |      NULL |     60 |
| CS3071F2011 | A1        |      NULL |     71 |
| CS3071F2011 | A2        |      NULL |     71 |
| CS3071F2011 | A5        |      NULL |     71 |
| CS3071F2011 | A7        |      NULL |     71 |
| CS3071F2011 | A3        |      NULL |     71 |
| CS3071F2011 | A4        |      NULL |     71 |
+-------------+-----------+-----------+--------+

以下是查询的结果。

+-----------+-----------+------------+---------+---------+---------+----------+
| studentId | Last Name | First Name | Quiz 60 | Quiz 64 | Quiz 71 | Averages |
+-----------+-----------+------------+---------+---------+---------+----------+
| A1        | harry     | thomas     |       0 |       0 |       0 |   0.0000 |
| A2        | harry     | willy      |       0 |       0 |       0 |   0.0000 |
| A3        | billy     | gregory    |       0 |       0 |       0 |   0.0000 |
| A4        | goat      | bobb       |       0 |       0 |       0 |   0.0000 |
| A5        | nogood    | tom        |       0 |       0 |       0 |     NULL |
| A7        | foobar    | dick       |       0 |       0 |       0 |     NULL |
+-----------+-----------+------------+---------+---------+---------+----------+

查询的预期结果是所有平均值为0.0000,为什么最后两个变化?

此外,每当我进行查询以便我一次只能得到一名学生A5和A7仍然显示为NULL而其余部分显示正常......


此问题的解决方案或实现相同目标的替代查询是可以接受的。我的目标是得到一个表格,每一行代表班上每个学生,他们在所有测验中的成绩以及学生所有测验的平均值。

3 个答案:

答案 0 :(得分:2)

你的所有quizGrade值都是NULL,你在数学计算中使用它((sum(quizGrade*(1-abs(sign(quizId-60))))。一旦db NULL进入几乎任何类型的操作,整个操作就变为null。问题应该是这就是为什么最后两个是空的,但为什么前四个不是。

答案 1 :(得分:0)

学生是否会为同一个quizid提供多个测验分数(在这个例子中,它与我想象的一对一)?如果没有,那么你可以使用

 avg( if(quizGrade, quizGrade, 0) ) as Averages

答案 2 :(得分:0)

对于A7,没有成绩。这在平均值中返回NULL。其中包含NULL的任何内容的平均值始终为NULL。

解决此问题的最简单方法是使用函数IFNULL。这可以用其他东西替换NULL值。如:

(sum(ifnull(quizGrade*(1-abs(sign(quizId-60))),0)) + 
sum(ifnull(quizGrade*(1-abs(sign(quizId-64))),0)) + 
sum(ifnull(quizGrade*(1-abs(sign(quizId-71)))),0 )/3 
as Averages 

我希望我已正确放置(